Сохранение данных из выпадающего списка в модель
Добрый день!
Возникла проблема с выпадающим списком, а точнее с сохранением из него данных.
Приведу простой пример.
Модель имеет вид (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 в отдельную таблицу в базе данных и вытягивать от туда или еще как-то?
Do you like it? Share on social networks!
- Last comments
- AKApril 1, 2025, 11:41 a.m.Добрый день. В данный момент работаю над проектом, где необходимо выводить звук из программы в определенное аудиоустройство (колонки, наушники, виртуальный кабель и т.д). Пишу на Qt5.12.12 поско…
- VPMarch 9, 2025, 4:14 p.m.Здравствуйте! Я устанавливал Qt6 из исходников а также Qt Creator по отдельности. Все компоненты, связанные с разработкой для Android, установлены. Кроме одного... Когда пытаюсь скомпилиров…
- ИМNov. 22, 2024, 9:51 p.m.Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
- Now discuss on the forum
- МАApril 1, 2025, 4:21 p.m.0ff763fe-4e50-455d-a3a6-5699c243b1a5_17_44_22_1.xml
- fFeb. 15, 2025, 1:46 p.m.Подскажите, пожалуйста! Как данный класс можно дополнить, чтобы созданные объекты можно было перемещать мышкой по сцене?
- Не запускается компьютер (точнее работает блок , но сам монитор вообще жесть)В общем я ничего с интернета не скачивала в последнее время. На компе никаких левых пр…
- Вопрос решен. Узнать QModelIndex элемента на который мы перетаскиваем другой элемент, можно с помощью функции indexAt(event->position().toPoint()) представления QTreeViev вызываемой в переопр…
Добрый день!
Так у вас в модели поде 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) вместо обычных вьюшек. Так лучше будет, в будущем оцените.
Спасибо.