在运行时如何修改Django表单?

4 投票
2 回答
2133 浏览
提问于 2025-04-16 20:10

我用的代码是:

class VoteForm(forms.ModelForm):
    other_choice1 = forms.BooleanField(required=False)
    other_choice2 = forms.BooleanField(required=False)
    other_choice3 = forms.BooleanField(required=False)
    other_choice4 = forms.BooleanField(required=False)

    class Meta:
        model = Vote
        exclude = ('choice', 'other_choices',)

    def __init__(self, poll_id, *args, **kwargs):
        super(VoteForm, self).__init__(*args, **kwargs)
        p = get_object_or_404(Poll, pk=poll_id)
        choices = p.choice_set.all()
        choices_len = len(choices)
        f = ['other_choice1','other_choice2','other_choice3','other_choice4']
        for i in range(0,choices_len):
           self.fields[f[i]].label = str(choices[i])
        for i in range(choices_len,4):
           del self.fields[f[i]]

这是我找到的在运行时修改表单字段的最好方法。看起来有点像是在破解实现。有没有什么更规范的方法来做到这一点?

谢谢,
亚历克斯

2 个回答

1

是的,这看起来确实有点不太正规。不过,这个问题的根本原因在于你的思路不太对。你似乎想要的是每个项目都有一个单独的复选框,但你却试图通过为每个项目设置一个布尔字段来实现。这其实不是正确的思路。你应该考虑用一个字段来表示这些项目,然后用一个复选框多选的工具来实际显示这些复选框。

4

使用 base_fields,具体可以参考这个链接:如何修改Django表单类?

ContactForm.another_field = forms.CharField(...)
ContactForm.base_fields['another_field'] = ContactForm.another_field

(或者使用 BaseForm,详细说明可以查看这里:http://snipt.net/danfreak/how-to-generate-a-dynamic-at-runtime-form-in-django/):

def make_contact_form(user):
    fields = { 'name': forms.CharField(max_length=50),
               'email': forms.EmailField(),
               'message': forms.CharField(widget=forms.Textarea) }
    if not user.is_authenticated:
        fields['captcha'] = CaptchaField()
    return type('ContactForm', [forms.BaseForm], { 'base_fields': fields })

)

撰写回答