Changes between Initial Version and Version 1 of CookBookNewFormsDynamicFields


Ignore:
Timestamp:
Dec 28, 2007, 9:08:24 PM (17 years ago)
Author:
Todd O'Bryan
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • CookBookNewFormsDynamicFields

    v1 v1  
     1= Creating Fields with Dynamic Forms =
     2
     3Imagine you're creating a Django app to deal with, oh, user polls or something silly like that. You could create a form that includes a place for the pollee to enter his/her name, age, and to answer a question.
     4{{{
     5import django.newforms as forms
     6
     7class Survey(forms.Form):
     8    name = forms.CharField(max_length=20)
     9    age = forms.IntegerField()
     10    answer = forms.ChoiceField(choices=(('0', 'Not at All'),
     11                                        ('1', 'Sometimes'),
     12                                        ('2', 'Often'),
     13                                        ('3', 'Always')))
     14}}}
     15When you display this, you'll get a nice form with three places to input information.
     16
     17But what if you're allowing your users to create their own survey questions, so that you don't know ahead of time how many answers you'll need? Luckily, you can add fields to the form as you're constructing it, in addition to specifying them as class attributes. If you have all your survey questions in a list (let's call it `questions` just to be confusing), you could create a `Survey` class that looks like this:
     18{{{
     19class Survey(forms.Form):
     20    name = forms.CharField(max_length=20)
     21    age = forms.IntegerField()
     22
     23    def __init__(questions, *args, **kwargs):
     24        super(Survey, self).__init__(*args, **kwargs)
     25        # now we add each question individually
     26        for i in range(len(questions)):
     27             self.fields['question_%d' % i] = forms.ChoiceField(label=questions[i], ...)
     28}}}
     29
     30When you display this form, you'll get separate spot to answer each of the questions you passed in, each with its own index so that you can match it to the question. One complication--if you choose to use this method, you have to pass the same `questions` list each time you create the form, both on the GET when it's empty and on the POST when it has your answers. It is possible to avoid this, but it takes a little more thought when you set up your views and the workflow. (Saving stuff in the session can make things much easier.)
     31
     32This technique isn't limited to defining new fields. You can also set a field's `initial` value in the `__init__` method, which is really helpful when your forms depend on your models, but don't match up exactly so you can't use the `ModelForm` framework.
Back to Top