What is the best way to change django form at runtime?

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 = ('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]] 

This is the best way to change form fields at run time. This is like a hack implementation. How can this be done?

Thanks Alex

+4
source share
2 answers

Use base_fields as described in Monkey fixing a Django form class? :

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

(Or BaseForm , as described 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 }) ) 
+4
source

Yes, that seems hacked. But the reason is that you are thinking in the wrong direction. What you think is necessary is a single flag for each element in the relationship, and you are trying to implement it by having one BooleanField for each element. But not how you should think in general - you should think of one field to represent the elements in this relationship and the ChecbkoxMultipleSelect widget to display the checkboxes.

+1
source

All Articles