Login

Form rendering using a template instead of builtin HTML

Author:
leoh
Posted:
June 4, 2007
Language:
Python
Version:
.96
Tags:
template newforms rendering
Score:
4 (after 4 ratings)

As an alternative to using forms rendered with the default hard-coded html, this factory function will take a template name as argument, and return a Form class based on django.newforms.BaseForm, which will render each form field using the supplied template.

As an example, I'm using this class as follows in one project (slightly edited with respect to project and app names):

# Get a form class which renders fields using a given template
CustomForm = proj.utils.makeTemplatedForm(template="app/formfield.html")

# Get base form class for the details model
BaseAppForm = forms.form_for_model(models.AppDetail, form=CustomForm)

using this template:

{% if errors %}
<ul class="errorlist">
   {% for error in errors %}
   <li>{{ error }}</li>
   {% endfor %}
</ul>
{% endif %}
{% if field.required %}<span class="required">*</span>{% endif %}{{ text }}
{{ help_text }}
 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
from django.utils.html import escape

def makeTemplatedForm(template=None):
    """Create a form class which formats its fields using the provided template.

    The template is given a dictionary containing the following key-value
    pairs:

        "label":        field label, if any,
        "errors":       list of errors, if any,
        "text":         widget rendering for an unbound form / field value for a bound form,
        "help_text":    field help text, if any
    """
    from django.template import loader
    import django.newforms as forms

    class TemplatedForm(forms.BaseForm):
        _template = template
        def __getitem__(self, name):
            "Returns a rendered field with the given name."
            #syslog.syslog("FormattingForm.__getitem__(%s)" % (name, ))
            try:
                field = self.fields[name]
            except KeyError:
                raise KeyError('Key %r not found in Form' % name)
            if not isinstance(field, forms.fields.Field):
                return field
            bf = forms.forms.BoundField(self, field, name)
            errors = [escape(error) for error in bf.errors]
            rendering = loader.render_to_string(self._template, { "errors": errors, "label": bf.label, "text": unicode(bf), "help_text": field.help_text, "field":field })
            return rendering
    return TemplatedForm

More like this

  1. load m2m fields objects by dirol 5 years, 1 month ago
  2. BetterForm with fieldsets and row_attrs by carljm 6 years, 5 months ago
  3. Notifications Middleware for Session-Backed Messages by tclineks 6 years, 11 months ago
  4. NewForms Readonly / Edit Pattern by FreddieP 7 years, 7 months ago
  5. Multiple-Submit-Button Widget for Choice Field by Archatas 6 years, 11 months ago

Comments

Please login first before commenting.