【问题标题】:Django - ModelChoiceField empty choice missingDjango - 缺少 ModelChoiceField 空选项
【发布时间】:2013-09-03 13:39:53
【问题描述】:

Django 文档说,当在表单上使用 ModelChoiceField 并且表单设置为 required=False 并且模型设置为 blank=True 除了没有默认值之外,那么我应该在我的选择标签中收到一个免费的空选项。我不是。有什么想法让我失去了空洞的选择吗?

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)

模板.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>

【问题讨论】:

    标签: python django


    【解决方案1】:

    您可以在ModelChoiceField 上使用empty_label

    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

    【讨论】:

      【解决方案2】:

      我知道,你半年前问过,但我想我还是发布了另一个答案。因为我认为有一个更优雅的解决方案,它使用您可以在表单中定义的“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 文档:

      【讨论】:

        【解决方案3】:

        如果您允许 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 }}
        

        【讨论】:

        • 谢谢,这就是解决方案。
        猜你喜欢
        • 2012-04-20
        • 2012-04-20
        • 2015-05-29
        • 1970-01-01
        • 2023-04-02
        • 2020-11-20
        • 1970-01-01
        • 2018-07-26
        • 2022-12-09
        相关资源
        最近更新 更多