Easier prefix handling for forms

 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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
from django.forms import BaseForm, Field, HiddenInput


class AutoPrefixedForm(BaseForm):
    '''A Form type that handles prefixes transparently.

    If a (non empty) prefix is passed, forms of this class have a hidden field
    named ``self.PREFIX_FIELD_NAME`` (by default "``PREFIX``") and value the prefix.
    Additionally, bound forms probe the passed data for this hidden field and set
    the prefix to it if found (and no prefix was passed explicitly at initialization).
    '''
    PREFIX_FIELD_NAME = 'PREFIX'

    def __init__(self, *args, **kwargs):
        super(AutoPrefixedForm, self).__init__(*args, **kwargs)
        if not self.prefix and self.data:
            self.prefix = self.data.get(self.PREFIX_FIELD_NAME)
        if self.prefix:
            self.fields[self.PREFIX_FIELD_NAME] = Field(widget=HiddenInput,
                                                        initial=self.prefix)

    def add_prefix(self, field_name):
        if field_name == self.PREFIX_FIELD_NAME:
            return field_name
        return super(AutoPrefixedForm,self).add_prefix(field_name)


def autoprefixed(field_name=AutoPrefixedForm.PREFIX_FIELD_NAME):
    '''Decorates a Form class so that it handles prefixes transparently, as if
    subclassing :class:`AutoPrefixedForm`.

    Usage::

        @autoprefixed
        class MyForm(forms.Form):
            ...

        or

        @autoprefixed(field_name='__prefix__')
        class MyForm(forms.Form):
            ...
    '''
    if isinstance(field_name, type):
        return autoprefixed()(field_name)
    def decorator(cls):
        if not issubclass(cls, AutoPrefixedForm):
            cls.__bases__ = (AutoPrefixedForm,) + cls.__bases__
        cls.PREFIX_FIELD_NAME = field_name
        return cls
    return decorator


#==== usage ===================

@autoprefixed
class ContactForm(forms.Form):
    subject = forms.CharField(max_length=100)
    message = forms.CharField()
    sender = forms.EmailField()
    cc_myself = forms.BooleanField(required=False)

f = ContactForm(prefix='bugform')
print f.fields.keys()   # ['subject', 'message', 'sender', 'cc_myself', 'PREFIX']

post_data = {
    'bugform-subject': 'hello',
    'bugform-message': 'Hi there',
    'bugform-sender': 'foo@example.com',
    'bugform-cc_myself': True,
    'PREFIX': 'bugform',
}
# don't need to pass 'prefix'
f = ContactForm(post_data)

print f.prefix        # 'bugform'
print f.is_valid()    # True
print f.cleaned_data  # {'PREFIX': 'bugform', 'cc_myself': True, 'message': u'Hi there',
                      #  'sender': u'foo@example.com', 'subject': u'hello'}

More like this

  1. Complex Formsets by smagala 5 years, 3 months ago
  2. Complex Form Preview by smagala 5 years ago
  3. Form with Two InlineFormSets by maeck 5 years, 4 months ago
  4. newforms self-contained login form by miracle2k 6 years, 9 months ago
  5. Formset Form by stephen_mcd 4 years, 1 month ago

Comments

(Forgotten your password?)