我在Django 1.3上使用ModelForm。
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用户(Here)提出了同样的问题。我已经在那里尝试了可接受的解决方案(如你所见),但这对我不起作用。
答案 0 :(得分:9)
即使没有空白= True,它也会显示额外输入。我创建了一个新的Widget:
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)
答案 1 :(得分:5)
设置blank=False
(或只删除它)并添加default='Unspecified'
答案 2 :(得分:1)
您可以在设置窗口小部件时设置选项。它显示----因为在你的模型中你有空白=真。
只需使用窗口小部件的选项arg并将其设置为您在模型中设置的选项。
答案 3 :(得分:1)
默认情况下,ModelChoiceField
使用的窗口小部件在列表顶部会有一个空选项。
您可以使用empty_label属性更改此标签的文本(默认为“---------”),也可以通过将empty_label设置为None来完全禁用空标签:
自定义空标签:
field1 = forms.ModelChoiceField(queryset=..., empty_label="(Nothing)")
没有空标签:
field2 = forms.ModelChoiceField(queryset=..., empty_label=None)
答案 4 :(得分:0)
Django <= 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)
Django> = 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)