Пустой Ярлык ChoiceField Django
Как заставить метку ChoiceField вести себя как ModelChoiceField? Есть ли способ установить empty_label или, по крайней мере, показать пустое поле?
Forms.py:
thing = forms.ModelChoiceField(queryset=Thing.objects.all(), empty_label='Label')
color = forms.ChoiceField(choices=COLORS)
year = forms.ChoiceField(choices=YEAR_CHOICES)
Я попробовал решения, предложенные здесь:
Переполнение стека Q - установка CHOICES = [('','All')] + CHOICES привела к внутренней ошибке сервера.
Переполнение стека Q2 - после определения ('', '---------'), в моем выборе, по-прежнему по умолчанию используется первый пункт в списке, а не выбор ('', '---------'),.
Gist - попробовал использовать EmptyChoiceField определено здесь, но не работает с использованием Django 1.4.
Но ни один из них не работал на меня.. Как бы вы решили эту проблему? Спасибо за ваши идеи!
6 ответов:
Смотрите документацию Django 1.11 поChoiceField . Поле 'empty_value' для поля выбора определяется как пустая строка ", поэтому ваш список кортежей должен содержать ключ", сопоставленный с любым значением, которое вы хотите показать для пустого значения.
### forms.py from django.forms import Form, ChoiceField CHOICE_LIST = [ ('', '----'), # replace the value '----' with whatever you want, it won't matter (1, 'Rock'), (2, 'Hard Place') ] class SomeForm (Form): some_choice = ChoiceField(choices=CHOICE_LIST, required=False)Примечание, Вы можете избежать ошибки формы, если хотите, чтобы поле формы было необязательным, используя 'required=False'
Кроме того, если у вас уже есть CHOICE_LIST без empty_value, вы можете вставить его, чтобы он появился первым в списке. раскрывающееся меню формы:
CHOICE_LIST.insert(0, ('', '----'))
Вот решение, которое я использовал:
from myapp.models import COLORS COLORS_EMPTY = [('','---------')] + COLORS class ColorBrowseForm(forms.Form): color = forms.ChoiceField(choices=COLORS_EMPTY, required=False, widget=forms.Select(attrs={'onchange': 'this.form.submit();'}))
Вы можете попробовать это (предполагая, что ваш выбор-это кортежи):
blank_choice = (('', '---------'),) ... color = forms.ChoiceField(choices=blank_choice + COLORS) year = forms.ChoiceField(choices=blank_choice + YEAR_CHOICES)Кроме того, я не могу сказать из вашего кода, является ли это формой или формой модели, но это последнее, нет необходимости переопределять поле формы здесь (вы можете включить choices=COLORS и choices=YEAR_CHOICES непосредственно в поле модели.
Надеюсь, это поможет.
Я знаю, что вы уже приняли ответ, но я просто хочу опубликовать это на случай, если кто-то там столкнется с проблемой, которую я имел, а именно принятое решение не работает с ValueListQuerySet. Поле EmptyChoiceField , на которое вы ссылаетесь, отлично работает для меня (хотя я использую django 1.7).
class EmptyChoiceField(forms.ChoiceField): def __init__(self, choices=(), empty_label=None, required=True, widget=None, label=None, initial=None, help_text=None, *args, **kwargs): # prepend an empty label if it exists (and field is not required!) if not required and empty_label is not None: choices = tuple([(u'', empty_label)] + list(choices)) super(EmptyChoiceField, self).__init__(choices=choices, required=required, widget=widget, label=label, initial=initial, help_text=help_text, *args, **kwargs) class FilterForm(forms.ModelForm): #place your other fields here state = EmptyChoiceField(choices=People.objects.all().values_list("state", "state").distinct(), required=False, empty_label="Show All")
Пришлось использовать 0 вместо u" из-за целого поля в модели. (Ошибка была недопустимым литералом для int () с базой 10: ')
Добавьте пустую метку, если она существует (и поле не требуется!)
if not required and empty_label is not None: choices = tuple([(0, empty_label)] + list(choices))
немного опоздал на вечеринку..
Как насчет того, чтобы вообще не изменять выбор и просто обрабатывать его с помощью виджета?
from django.db.models import BLANK_CHOICE_DASH class EmptySelect(Select): empty_value = BLANK_CHOICE_DASH[0] empty_label = BLANK_CHOICE_DASH[1] @property def choices(self): yield (self.empty_value, self.empty_label,) for choice in self._choices: yield choice @choices.setter def choices(self, val): self._choices = valТогда просто назовите его:
class SomeForm(forms.Form): # thing = forms.ModelChoiceField(queryset=Thing.objects.all(), empty_label='Label') color = forms.ChoiceField(choices=COLORS, widget=EmptySelect) year = forms.ChoiceField(choices=YEAR_CHOICES, widget=EmptySelect)Естественно, что
EmptySelectбудет помещен в какой-то кодcommon/widgets.py, а затем, когда вам это понадобится, просто ссылайтесь на него.
Comments