我使用的代码是:
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]]
这是我发现在运行时修改表单字段的最佳方法。这似乎有点像黑客攻击实现。什么是定义明确的方法?
谢谢, 亚历
答案 0 :(得分:4)
按照Monkey patching a Django form class?:
中的说明使用base_fields
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 })
)
答案 1 :(得分:1)
是的,这看起来确实很糟糕。但原因是你在思考方向错误。你似乎想要的是一个关系中每个项目的单一复选框,你试图通过每个项目有一个BooleanField来实现它。但这不是你应该如何思考的 - 你应该考虑用一个字段来表示该关系中的项目,以及一个ChecbkoxMultipleSelect小部件来实际显示复选框。