views:

29

answers:

1

I want to build a system using Django that will allow users to build forms, store them and have their customers use them. I know how I can go about creating the forms dynamically but I'm looking for a good way to still use the form classes and handle many different user's dynamic forms in an elegant way.

I'm thinking of storing the form field information as a dictionary in the db. Is there any way in django to re-interpret this dictionary back into a form object? Or do I have to write a routine that will simply interpret and build out a form in html myself?

If someone knows where to point me to the info I'd really appreciate it.

+2  A: 

This is a Python question more than a Django question, whence my tag edit.

To reproduce the equivalent of, say:

class MyForm(forms.Form):
    foo = forms.CharField(max_length=100)

you need something like:

f = type(forms.Form)('MyForm', forms.Form, d)

where d is a dictionary like:

d = { 'foo': forms.CharField(max_length=100) }

Of course, in the end the form class will be bound to name f (you can use setattr to bind it to qualified name something.MyForm for an appropriate something, but please don't even dream of binding it to a bare name that's dynamically variables -- it would also be a nightmare to use such a barename!).

So, to recreate the form class object at runtime, you need to preserve:

  1. its name MyForm
  2. a dict with the field names as keys and the field objects as values

and to make point 2 work, you similarly need to preserve for each field (besides its name) the type name (so you can recover the type with a getattr from forms) and its named parameters (as a dict), so you can basically do

d[fieldname] = getattr(forms, fieldtypename)(**fieldparameters)

based on strings fieldname and fieldtypename and dict fieldparameters, for each field, as you rebuild dictionary d (i.e., prepare to satisfy step 2 of the above short list;-).

Alex Martelli
You can also pickle objects and store them in the database. However, I think you may run into issues as Alex hints with varying names.
Matthew Schinckel
Thanks! I actually did more digging after posting the question and found a good article on how to do this using django,James Bennett's Dynamic form article.
From James article you should refer to forms.BaseForm rather than forms.Form
f = type(forms.Form)('MyForm', forms.Form, d) becomes f = type(forms.Form)('MyForm', forms.BaseForm, d)