This is a little snippet that you can use to make your Django newforms dynamic at runtime. You can define an arbitrary number of fields of the form without loosing newforms capibilites. You can render the form dynamically be "misusing" the "help_text" attribute of the form fields (Every form field allows the definition of this attribute). This way you can search for changes in the help_text of every field and render the form accordingly.
The form itself is dynamically defined in the view.
The form state can be saved in a Django Session Variable (specifically for Linux users with a process-based Apache Server), so that you can rebuild and verify a submitted 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
- Template tag - list punctuation for a list of items by shapiromatron 10 months, 2 weeks ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 3 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
- Help text hyperlinks by sa2812 1 year, 7 months ago
Comments
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
#
How can i use this? thanks
#
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:
#
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']
#
My modifications for accessing cleaned_data:
#
Hi, imho it is good to add to it a function "is_valid". So form can be used as always.
#
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)
#
Please login first before commenting.