Поле выбора заказа Django

Я боролся с полями выбора Django в форме. У меня есть выбор в form.py и поле выбора радио.

DURATION_CHOICES = {
    (1, '30'),
    (2, '45'),
    (3, '60'),
    (4, '75'),
    (5, '90'),
    (6, '105'),
    (7, '120+'),
}

duration = forms.ChoiceField(choices=DURATION_CHOICES, widget=forms.widgets.RadioSelect, label_suffix="", label="Trainingsdauer in Minuten",)

Однако, когда я открываю форму для создания нового сеанса обучения, поле выбора длительности радио выбирается случайным образом, т. е. 105 находится в списке перед 45. Порядок даже меняется от тестовых устройств к другому.

У меня такая же проблема с полями выбора из models.py

Я уже заказал свои варианты, но как мне получить упорядоченный список вариантов в моей форме?


person Matthias Hügli    schedule 21.05.2018    source источник
comment
Здесь вы определили набор или список.   -  person Willem Van Onsem    schedule 21.05.2018


Ответы (1)


Я думаю, что это больше проблема с коллекцией, которую вы используете. Здесь вы используете фигурные кавычки ({}). Это set. Набор представляет собой неупорядоченный набор хэшируемых элементов, которые встречаются ноль или один раз. Но, как сказано, коллекция неупорядочена. Это означает, что нет никаких гарантий, если вы перечислите коллекцию, в каком порядке вы ее извлечете.

Используйте список или кортеж

Я думаю, вам лучше использовать здесь list или tuple, которые представляют собой упорядоченный набор элементов. Для списков можно использовать квадратные скобки ([]), для кортежей — круглые скобки (()):

DURATION_CHOICES = [
    (1, '30'),
    (2, '45'),
    (3, '60'),
    (4, '75'),
    (5, '90'),
    (6, '105'),
    (7, '120+'),
]

Отсортируйте коллекцию, прежде чем передать ее в качестве аргумента

Если вы хотите продолжать использовать набор, мы можем преобразовать его в список перед добавлением в поле. Например, мы можем использовать sorted(..) для сортировки по первому элементу кортежа:

from operator import itemgetter

duration = forms.ChoiceField(
    choices=sorted(DURATION_CHOICES, key=itemgetter(0)),
    widget=forms.widgets.RadioSelect,
    label="Trainingsdauer in Minuten",
)

Однако обратите внимание, что если вы внесете изменения в набор DURATION_CHOICES, эти изменения не отразятся в наборе ChoiceField, поскольку здесь мы сделали поверхностную копию списка.

person Willem Van Onsem    schedule 21.05.2018
comment
@EminBuğraSaral: есть разница между словарем и набором. stackoverflow.com/questions/34370599/ Список элементов, разделенных запятыми и заключенный в фигурные скобки, является набором, если элементы содержат два выражения, разделенных двоеточием, то это словарь. - person Willem Van Onsem; 21.05.2018
comment
Я не уделял должного внимания. Извините за мое редактирование, пожалуйста. - person Emin Bugra Saral; 21.05.2018
comment
Спасибо @WillemVanOnsem. Я определенно не уделял должного внимания типу коллекции. Очень ценю ваше объяснение - person Matthias Hügli; 21.05.2018