I've recently had a situation where I needed to create dynamic forms
and corresponding code to handle them.

One thing that you should know about python is that there's nothing
special about classes, you can take a collection of attributes and
methods and use them to create a new class on-the-fly using python's
type() function. You can use this to dynamically build a form class
with a new field.

My roommate wrote a great blog post on how to do build classes
dynamically (http://askawizard.blogspot.com/2008/09/metaclasses-python-
saga-part-4_30.html), which you should read before attempting this.

Once you understand what that is talking about (or not), you end up
writing some code like this:

If you want this form to be dynamic:

class MyDynamicForm(Form):
    foo = CharField(max_len = 100)
    bar = IntegerField()
    def clean_foo(self):
        value = self.cleaned_data['foo']
        if value != 'foo':
            raise ValidationError('foo is not foo!')
    def clean_bar(self):
        value = self.cleaned_data['bar']
        if value != 42:
            raise ValidationError('wrong answer')

You could build it programatically with:

# Our base classes (which you could build programatically if you
wanted)
bases  = (Form,)

# Our class attributes
attys  = {
    'foo' : CharField(max_len = 100),
    'bar' : IntegerField(),
}

# This returns a clean method built from some parameters
def general_clean(name, correct_value, error_text):
    def inner(self):
        value = self.cleaned_data[name]
        if value != correct_value:
            raise ValidationError(error_text)
    return inner

# Now add the clean methods. You could just define methods and assign,
but this illustrates generating them programatically.
for name, correct_value, error_text in (
    ('foo', 'foo', 'foo is not foo!'),
    ('bar', 42, 'wrong answer'),
):
    attys['clean_' + name] = general_clean(name, correct_value,
error_text)

# Now, to create the dynamic class, you need the following
incantation:
DynamicForm = getattr(Form, '__metaclass__', type)('DynamicForm',
bases, attys)

# That only creates the *class*, we still have to create an instance
form = DynamicForm({'foo': 'foo', 'bar': 42})

Does this help? It would let you dynamically add elements and handlers
to the form that django is aware of, thus you get all the benefits of
using the form framework. Let me know if this is a bit thick and I'll
be happy to explain it and perhaps blog a more coherent example.

--Ryan



--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to