Сохранение данных из выпадающего списка в модель
Добрый день!
Возникла проблема с выпадающим списком, а точнее с сохранением из него данных.
Приведу простой пример.
Модель имеет вид (models.py)
from django.db import models # Create your models here. class Test(models.Model): METRIC = 'metric' IMPERIAL = 'imperial' ATHER = '' UNIT = ( (METRIC, 'kg'), (IMPERIAL, 'lb'), (ATHER, 'none') ) name = models.CharField(max_length=25) temperature_unit = models.CharField(max_length=8, choices=UNIT, default=METRIC) def __str__(self): return self.name class Meta: verbose_name_plural = 'tests'
Файл forms.py
from django.forms import ModelForm, TextInput from .models import Test class TestForm(ModelForm): class Meta: model = Test fields = ['name', 'unit'] widgets = {'name': TextInput(attrs={'class': 'input', 'placeholder': 'Name'})}
Файл *.html
<form method="POST"> {% csrf_token %} <div class="field has-addons"> <div class="control is-expanded"> {{ form.name }} </div> <select> {% for temp in form.tunit %} <option value=""{{ temp.data.value }}>{{ temp.data.label }}</option> {% endfor %} </select> <div class="control"> <button type="submit" class="button is-info"> Add Unit </button> </div> </div> </form>
В результате в качестве value выпадающего списка (temp.data.value) оказывается 'metric', 'imperial' и '', а в самом выпадающем списке на странице оказывается (temp.data.label): kg, lb, none. Как и должно быть.
Только при вводе данных в поле формы (name = models.CharField(max_length=25)) и попытке сохранения вылетает ошибка. В результате просмотра request.POST в нем оказывается только значение 'name' без 'unit'.
Файл views.py
import requests from django.shortcuts import render from .models import Test from .forms import TestForm def index(request): url = 'http://api.site.org/data/2.5/?q={}&units={}&id=1111&appid=111111111' if request.method == 'POST': # Здесь request.POST нет данных unit только name # Вылетает ошибка form = TestForm(request.POST) form.save() tests = Test.objects.all() test_data = [] for test in tests: # Преобразование данных из metric в kg итд. r = requests.get(url.format(test, test.unit)).json() res = [data for (t_type, data) in Test.UNIT if t_type == test.unit] test_w = { 'name': test.name, 'unit': res[0], 'temp': r['main']['temp'], 'description': r['data'][0]['description'], 'icon': r['data'][0]['icon'], } test_data.append(test_w) context = {'test_data': test_data, 'form': form} return render(request, 'module/module.html', context)
Что я делаю не так?
Возможно есть другой способ более правильный:
поместить данные о unit в отдельную таблицу в базе данных и вытягивать от туда или еще как-то?
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.Do you like it? Share on social networks!
- Akiv Doros
- Nov. 11, 2024, 2:58 p.m.
C ++ - Test 004. Pointers, Arrays and Loops
- Result:50points,
- Rating points-4
- molni99
- Oct. 26, 2024, 1:37 a.m.
C ++ - Test 004. Pointers, Arrays and Loops
- Result:80points,
- Rating points4
- molni99
- Oct. 26, 2024, 1:29 a.m.
C ++ - Test 004. Pointers, Arrays and Loops
- Result:20points,
- Rating points-10
Добрый день!
Так у вас в модели поде unit объявлено как temperature_unit
Вы имя перепутали
Так нужно
Ну и так далее везде поменяйте unit на temperature_unit
Я уже поправил. Скопировал данные из реального и тестово проектов. Ошибка вышла. Извините. :(
Но вопрос остался
Посмотрел документацию, делаю правильно, но не работает.
я так понимаю, у вас там в шаблоне пропущены id и name поля, поэтому и пропускаются значения, а они там должны быть.
Вообще у Field есть методы для получения этих всех id и name, но я как-то не помню их, нужно в документации покопаться.
А так я использую django_bootstrap4, там эти моменты уже реализованы, так что всё автоматически работает. Не нужно всю эту вёрстку делать вручную.
Все исправил, все пересмотрел еще раз.
Понять не могу почему я в качестве request.POST при попытке сохранения данных, от формы получаю:
{'csrfmiddlewaretoken': 'BrD9OchYiCLJJAV3U8MX7NewnCO2uZ2EjmyfOIesySZp6dmcyoA1GRwnwReSch0T',
'name': 'Unit1'}
а не:
{'csrfmiddlewaretoken': 'BrD9OchYiCLJJAV3U8MX7NewnCO2uZ2EjmyfOIesySZp6dmcyoA1GRwnwReSch0T',
'name': 'Unit1', temperature_unit: 'kg'}
А как выглядит отрендеренная форма? В смысле html можете показать итоговый?
То есть открываете страницу с формой и через браузер посмотрите html и покажите, что там вышло.
Вот например у меня в одной из форм так получается.
После исправления:
Получаю:
{'csrfmiddlewaretoken': ['EvCSJRprJbsn3Rte7AxtnpeXeNO3pIThmqxYJnmVZrG3quUnLQlxWtwOn2eT70Rw'], 'name': ['Lviv'], 'temperature_unit': ['']}
Только что-бы я не выбрал в списке значение temperature_unit не меняется.
Форма выглядит так:
Пытаюсь на сайт притулить индикатор погоды с выбором в каких унитах показывать температеру.
Нет, вы не поняли, покажите мне отрендеренный html из консоли браузера.
Вот отсюда
Все ясно:
И кстати да, я увидел вашу ошибку,
вот ваш код
а вот как надо
Найдёте, где кавычки перепутали?
Нашел ошибку. Было:
option value=""{{ temperature.data.value }}>{{ temperature.data.label }}
Нужно:
option value="{{ temperature.data.value }}">{{ temperature.data.label }}
Оказывается все было правильно кроме кавычки :) Буду чаше заглядывать в Инспектор.
Огромное спасибо! :)
Я с консолью браузера при разработке на django вообще не расстаюсь. Иначе можно голову долго ломать.
Теперь так и буду делать :)
Если кому-то понадобится есть еще один вариант, который я думаю более верный:
models.py
views.py
Тоесть просто создал новую модель и все скинул туда.
Если вы создадите вручную несколько TempUnit, а потом только установка этих TempUnit через выпадающий список, то да, будет даже лучше.
Однако переходите к CBV (Class Based View) вместо обычных вьюшек. Так лучше будет, в будущем оцените.
Спасибо.