Пустой ярлык выбораField 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.
Но никто из них не работал у меня. Как бы вы решили эту проблему? Спасибо за ваши идеи!
Ответы
Ответ 1
Здесь решение, которое я использовал:
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();'}))
Ответ 2
См. Документацию Django 1.11 на ChoiceField. "Empty_value" для ChoiceField определяется как пустая строка '', поэтому ваш список кортежей должен содержать ключ '', сопоставленный с любым значением, которое вы хотите показать для пустого значения.
### 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, ('', '----'))
Ответ 3
Вы можете попробовать это (при условии, что ваш выбор - это кортежи):
blank_choice = (('', '---------'),)
...
color = forms.ChoiceField(choices=blank_choice + COLORS)
year = forms.ChoiceField(choices=blank_choice + YEAR_CHOICES)
Кроме того, я не могу сказать из вашего кода, является ли это формой или ModelForm, но это последнее, не нужно переопределять поле формы здесь (вы можете включить выбор = COLORS и choice = YEAR_CHOICES непосредственно в поле модели.
Надеюсь, это поможет.
Ответ 4
Я знаю, что вы уже приняли ответ, но я просто хочу опубликовать его, если кто-то из них сталкивается с проблемой, которую я имел, а именно, принятое решение не работает с 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")
Ответ 5
Пришлось использовать 0 вместо u '' из-за целочисленного поля в модели. (Ошибка была недопустимой буква для int() с базой 10: ')
добавьте пустую метку, если она существует (и поле не требуется!)
if not required and empty_label is not None:
choices = tuple([(0, empty_label)] + list(choices))
Ответ 6
Немного поздно на вечеринку..
Как насчет того, чтобы вообще не изменять выбор и просто обрабатывать его с помощью виджета?
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
код, а затем, когда он вам понадобится, просто common/widgets.py
к нему.
Ответ 7
Это не та форма, но я сделал это следующим образом, вдохновленным методом EmptyChoiceField:
from django import forms
from ..models import Operator
def parent_operators():
choices = Operator.objects.get_parent_operators().values_list('pk', 'name')
choices = tuple([(u'', 'Is main Operator')] + list(choices))
return choices
class OperatorForm(forms.ModelForm):
class Meta:
model = Operator
# fields = '__all__'
fields = ('name', 'abbr', 'parent', 'om_customer_id', 'om_customer_name', 'email', 'status')
def __init__(self, *args, **kwargs):
super(OperatorForm, self).__init__(*args, **kwargs)
self.fields['name'].widget.attrs.update({'class': 'form-control m-input form-control-sm'})
self.fields['abbr'].widget.attrs.update({'class': 'form-control m-input form-control-sm'})
self.fields['parent'].widget.attrs.update({'class': 'form-control m-input form-control-sm'})
self.fields['parent'].choices = parent_operators()
self.fields['parent'].required = False
self.fields['om_customer_id'].widget.attrs.update({'class': 'form-control m-input form-control-sm'})
self.fields['om_customer_name'].widget.attrs.update({'class': 'form-control m-input form-control-sm'})
self.fields['email'].widget.attrs.update({'class': 'form-control m-input form-control-sm', 'type': 'email'})enter code here