Login

Form rendering using a template instead of builtin HTML

Author:
leoh
Posted:
June 4, 2007
Language:
Python
Version:
.96
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. Template tag - list punctuation for a list of items by shapiromatron 10 months, 1 week ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 2 weeks ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 5 months ago
  5. Help text hyperlinks by sa2812 1 year, 6 months ago

Comments

Please login first before commenting.