Dynamic Django form

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
from django import newforms as forms

class DynForm(forms.Form):    
    """
    Dynamic form that allows the user to change and then verify the data that was parsed
    """
    def setFields(self, kwds):
        """
        Set the fields in the form
        """
        keys = kwds.keys()
        keys.sort()
        for k in keys:
            self.fields[k] = kwds[k]
            
    def setData(self, kwds):
        """
        Set the data to include in the form
        """
        keys = kwds.keys()
        keys.sort()
        for k in keys:
            self.data[k] = kwds[k]
            
    def validate(self, post):
        """
        Validate the contents of the form
        """
        for name,field in self.fields.items():
            try:
                field.clean(post[name])
            except ValidationError, e:
                self.errors[name] = e.messages

#### In the view ########################################################

# Form definition
# kwargs is a dictionary. The key being the name of the field and the value 
# being the type (CharField(kwargs*))
kwargs['a_name'] = forms.CharField(label="Name", max_length=25, help_text="name")
kwargs['b_lname'] = forms.CharField(label="Last Name", help_text="lname")
kwargs['c_bday'] = forms.DateField(label="Birthday", help_text="birthday")

# Creating the form object and manipulating/validating it
form = DynForm() # Create the form
form.setFields(kwargs) # Set the fields as defined in the kwargs dictionary
form.setData(request.POST) # Set the form data
form.validate(request.POST) # validate the from 

##########################################################################

More like this

  1. change a widget attribute in ModelForm without define the field by jedie 5 years, 8 months ago
  2. Render dynamically assigned fields in a template by rubic 7 years, 1 month ago
  3. Dynamic Regroup Template Tag by btaylordesign 2 years, 8 months ago
  4. Dynamic Form Class by dballanc 7 years ago
  5. SeparatedValuesField by jezdez 6 years, 4 months ago

Comments

mdales (on July 18, 2008):

This is great, but to make it work you need to modify setData to add the line:

self.is_bound = True

Otherwise when you display the form it ignores the data

#

balsagoth (on August 1, 2008):

How can i use this? thanks

#

mikeshantz (on August 12, 2008):

Nice. This came in handy, but it doesn't play well with multivalue fields.

I had to modify setData and validate to deal with this situation:

def setData(self, kwds):
    """Set the data to include in the form"""
    for name,field in self.fields.items():
        self.data[name] = field.widget.value_from_datadict(
                            kwds, self.files, self.add_prefix(name))
    self.is_bound = True

def validate(self, post):
    """Validate the contents of the form"""
    for name,field in self.fields.items():
        value = field.widget.value_from_datadict(
                            post, self.files, self.add_prefix(name))
        try:
            field.clean(value)
        except forms.ValidationError, e:
            self.errors[name] = e.messages

#

curaloucura (on August 19, 2008):

I couldn't find how I can access the cleaned_data and in fact why you are creating a different method validate instead of using self.full_clean() or something similar. I just changed the validate to:

def validate(self): self.full_clean()

for readability sake and now I can access:

dynform_instance.cleaned_data['myfield']

#

shreyankg (on May 19, 2011):

My modifications for accessing cleaned_data:

def validate(self, post):
    """
    Validate the contents of the form
    """
    self.cleaned_data = {}
    for name,field in self.fields.items():
        try:
            self.cleaned_data[name] = field.clean(post[name])
        except ValidationError, e:
            self.errors[name] = e.messages

#

vsergeyev (on October 6, 2011):

Hi, imho it is good to add to it a function "is_valid". So form can be used as always.

if form.is_valid():
    # process it

#

iceman3710 (on January 29, 2012):

Could you please explain, how can change repesentation of form in html?

I can easily wright {{form}} or {{form.as_table}}, but I want locate them by myself.

Should I do smth like {{form.fields[k]}} ? (I can't make this work)

#

(Forgotten your password?)