Как избавиться от фиктивного выбора, созданного RadioSelect of Django Form
Я использую ModelForm для Django 1.3.
models.py:
class UserProfile(models.Model):
...
gender = models.CharField(max_length=1, blank=True, choices=(('M', 'Male'), ('F', 'Female'), ('Unspecified', '')), default='M')
...
forms.py:
class UserProfileForm(ModelForm):
class Meta:
model = UserProfile
fields = ('gender')
widgets = {
'gender': forms.RadioSelect(),
}
Когда этот виджет отображается в HTML, я получил
<ul>
<li><label for="id_gender_0"><input type="radio" id="id_gender_0" value="" name="gender" />---------</label></li>
<li><label for="id_gender_1"><input checked="checked" type="radio" id="id_gender_1" value="M" name="gender" /> Male</label></li>
<li><label for="id_gender_2"><input type="radio" id="id_gender_2" value="F" name="gender" />Female</label></li>
<li><label for="id_gender_3"><input type="radio" id="id_gender_3" value="" name="gender" /> Unspecified</label></li>
</ul>
Проблема:
Как я могу избавиться от фиктивного выбора "--------"?
Та же проблема возникла еще одним пользователем stackoverflow месяцев назад (Здесь). Я попробовал принятое решение там (как вы можете видеть), но это не сработало для меня.
Ответы
Ответ 1
Даже без пустого = True показывает дополнительный ввод. Я создал новый виджет:
from itertools import chain
from django.forms import RadioSelect
from django.utils.encoding import force_unicode
class RadioSelectNotNull(RadioSelect):
def get_renderer(self, name, value, attrs=None, choices=()):
"""Returns an instance of the renderer."""
if value is None: value = ''
str_value = force_unicode(value) # Normalize to string.
final_attrs = self.build_attrs(attrs)
choices = list(chain(self.choices, choices))
if choices[0][0] == '':
choices.pop(0)
return self.renderer(name, str_value, final_attrs, choices)
Ответ 2
Установите blank=False
(или просто удалите его), а также добавьте default='Unspecified'
Ответ 3
Вы можете установить параметры при настройке виджета. Он показывает ----, потому что в вашей модели у вас пусто = True.
Просто используйте аргументы arg виджета и установите его в соответствии с параметрами, заданными в вашей модели.
Ответ 4
По умолчанию виджет, используемый ModelChoiceField
, будет иметь пустой выбор в верхней части списка.
Вы можете изменить текст этого ярлыка (который по умолчанию - "---------" ) с атрибутом empty_label, или вы можете полностью отключить пустую метку, установив для параметра empty_label значение None:
Пользовательская пустая метка:
field1 = forms.ModelChoiceField(queryset=..., empty_label="(Nothing)")
Нет пустой метки:
field2 = forms.ModelChoiceField(queryset=..., empty_label=None)
Ответ 5
Django & lt; = 1,10
Виджет RadioSelectNotNull
from itertools import chain
from django.forms import RadioSelect
from django.utils.encoding import force_unicode
class RadioSelectNotNull(RadioSelect):
"""
A widget which removes the default '-----' option from RadioSelect
"""
def get_renderer(self, name, value, attrs=None, choices=()):
"""Returns an instance of the renderer."""
if value is None: value = ''
str_value = force_unicode(value) # Normalize to string.
final_attrs = self.build_attrs(attrs)
choices = list(chain(self.choices, choices))
if choices[0][0] == '':
choices.pop(0)
return self.renderer(name, str_value, final_attrs, choices)
Джанго> = 1,11
Как и после Django 1.10, следующий метод больше не существует в RadioSelect или в его предках. Поэтому верхний виджет не удалит фиктивный выбор, созданный RadioSelect.
def get_renderer(self, name, value, attrs=None, choices=()):
Таким образом, чтобы убрать фиктивный выбор, сгенерированный RadioSelect, используйте следующий виджет. Я проверял это до Django 2.0
from django.forms import RadioSelect
class RadioSelectNotNull(RadioSelect):
"""
A widget which removes the default '-----' option from RadioSelect
"""
def optgroups(self, name, value, attrs=None):
"""Return a list of optgroups for this widget."""
if self.choices[0][0] == '':
self.choices.pop(0)
return super(RadioSelectNotNull, self).optgroups(name, value, attrs)