Django - 缺少ModelChoiceField空选择

时间:2013-08-30 18:36:19

标签: python django

Django文档说当在表单上使用ModelChoiceField并且表单设置为required = False并且model除了没有默认值之外设置为blank = True,那么我应该在select标签中收到一个空闲的空选择。我不是。对于我为失去空洞的选择而采取的行动有什么想法?

models.py

class Location(models.Model):
    location_name = models.CharField(max_length=50, blank=True)
    address = models.CharField(max_length=50)
    active = models.BooleanField(default=True)

    def __unicode__(self):
        return self.location_name

forms.py

class CalcForm(forms.Form):
    startAddr = forms.ModelChoiceField(queryset=Location.objects.all(), required=False)
    waypoint1 = forms.ModelChoiceField(queryset=Location.objects.all(), required=False)
    waypoint2 = forms.ModelChoiceField(queryset=Location.objects.all(), required=False)
    ...
    endAddr = forms.ModelChoiceField(queryset=Location.objects.all(), required=False)

template.html

<form action="../calcview" method="get">{% csrf_token% }
<label>
    <div>Start Address</div>
    <select name="startAddr">
        {% for location in form.fields.startAddr.queryset %}
            <option value = "{ location.location_name }">{{location.location_name}}/option>
        {% end for %}
    </select>
...
</form>

3 个答案:

答案 0 :(得分:5)

如果允许django表单自动呈现表单字段,则只会获得“空闲”空选项。因为你是在模板中自己渲染它(我不知道你为什么要这样做......)你需要自己添加空选:

<select name="startAddr">
    <option value="">-----------</option>
    {% for location in form.fields.startAddr.queryset %}    
        <option value = "{ location.location_name }">{{location.location_name}}</option>
    {% end for %}
</select>

您可以通过允许django表单为您呈现它来测试它:

<div>Start Address</div>
{{ form.startAddr }}

答案 1 :(得分:1)

我知道,你问过半年多了,但我想我还是会发布另一个答案。因为我认为有一个更优雅的解决方案,使用您可以在表单中定义的“empty_label”。

您可以通过模板中的form.fields.startAddr.empty_labelform.startAddr.field.empty_label访问此empty_label属性。所以你可以这样包括它:

<select id="{{ form.fields.startAddr.id_for_label }}" name="{{ form.fields.startAddr.html_name }}">
    <option value="">{{ form.fields.startAddr.empty_label }}</option>
    {% for location in form.fields.startAddr.queryset %}
        <option value="{{ location.location_name }}">{{ location.location_name }}/option>
    {% endfor %}
</select>

我想知道你是否真的不想使用{{ location.id }}作为价值?或者location_name是唯一的吗?因为它甚至可能是空的,所以自动生成的id可能更好作为参考。

正如您所看到的,我还将name="startAddr"替换为表单对象为每个字段提供的信息:id="{{ form.fields.startAddr.id_for_label }}" name="{{ form.fields.startAddr.html_name }}。使用这些变量可以使您的模板代码更加灵活和健壮。

有关详细信息,请查看Django文档:

答案 2 :(得分:0)

您可以在empty_label上使用ModelChoiceField

startAddr = forms.ModelChoiceField(empty_label='---------', queryset=Location.objects.all(), required=False)

然后将表单字段渲染到模板中。

{{ form.startAddr }}

https://docs.djangoproject.com/en/2.1/ref/forms/fields/#django.forms.ModelChoiceField.empty_label