开发者

what's the best way to modify django form at runtime?

开发者 https://www.devze.com 2023-03-15 12:45 出处:网络
The code I use is: class VoteForm(forms.ModelForm): other_choice1 = forms.BooleanField(required=False) other_choice2 = forms.BooleanField(required=False)

The code I use is:

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 = ('choic开发者_JS百科e', '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]]

This is the best way I've found to modify form's fields at runtime. It seems a bit like hacking the implementation. What's the well-defined way to do that?

Thanks, Alex


Use base_fields as explained in Monkey patching a Django form class? :

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

(Or BaseForm as explained here 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 })

)


Yes, this does seem hacky. But the reason for that is that you're thinking in the wrong direction. What you seem to want is a single checkbox for each item in a relationship, and you're trying to implement that by having one BooleanField per item. But that's not how you should be thinking at all - you should be thinking of a single field to represent the items in that relationship, and a ChecbkoxMultipleSelect widget to actually display the checkboxes.

0

精彩评论

暂无评论...
验证码 换一张
取 消