在Django表单中,如何遍历每个字段的单独选项?

5 投票
3 回答
3038 浏览
提问于 2025-04-17 06:10

我正在制作一个表单向导。在第一步,我有一个只有一个字段的表单。这个字段是一个外键。Django默认的外键控件会把这个字段的选项放在一个下拉菜单里,每个选项都是一个HTML选项。我把默认控件改成了单选按钮(RadioSelect),所以现在它通过单选按钮来显示字段的选项。

这是我的forms.py文件

class ChooseProductTypeForm(ModelForm):
    class Meta:
        model = Product
        widgets = {
            'type': RadioSelect,
        }

我想做的是能够循环遍历每个选项,并获取我在模型中存储的每个选项的特定数据。

我希望这能像这样简单:

{% for field in form %}
    {% for option in field %}
        {{ option.image }}
        {{ option.title }}
        {{ option.description }}
    {% endfor %}
{% endfor %}

经过一天半的研究,我决定看看社区的意见。顺便说一下,我找到了一些可行的解决方案,但都非常复杂。难道没有更简单的方法吗?

3 个回答

0

抱歉,但你希望的那种方式是无法遍历字段的。你想要遍历的东西其实不是一个查询集,而是一个 ModelChoiceField。你可以访问每个选项,但它们在内部是以二元组的形式表示的,第一个元素是外键的ID,第二个元素是 __unicode__ 的表示形式。

不过,正如你所说的,确实有办法解决这个问题。最好的方法,虽然有点麻烦,但可能是用一个字典把你需要的信息发送下来,使用模型ID作为键。你可以使用一个 values 查询集 来很容易地做到这一点。

0

我觉得这个问题可以用两种方法来解决。

第一种方法是为这个字段创建一个自定义的小部件,这样就可以显示每个选项的属性。这种方法是可行的,但我现在没时间把它写出来。

第二种方法更简单,就是在你的表单里添加一个函数来处理这个问题,并返回你想要的数据。

class ChooseProductTypeForm(ModelForm):
    def get_my_modelfield(self):
        for option in self.fields['my_modelfield'].queryset:
            yield {
              'image': option.image, 
              'title': option.title, 
              'description': option.description
           }

这样做主要是把数据库的内容和模板分开,只用一个简单易懂的表单函数来返回你需要的数据。如果表单字段将来有变化,你就不需要到处修改模板,只需更新这个函数就可以了。

不过,这种方法的缺点是你不能简单地循环遍历表单中的字段,而是需要逐个输出每个字段。当然,你也可以尝试在表单上使用 __iter__,但那样可能会有点复杂。我不太确定你具体在处理什么情况呢 :)

8

你可以访问选择的查询集,但要注意,模板可能不是处理这种逻辑的合适地方。顺便提一下,field.field 这不是打错字哦。

{% for field in form %}
    {% for option in field.field.choices.queryset %}
        {{ option.image }}
        {{ option.title }}
        {{ option.description }}
    {% endfor %}
{% endfor %}

撰写回答