| 1 | == Subclassing newforms Form.form to rendering form via django template == |
| 2 | |
| 3 | Sometimes standard methods of rendering HTML/XML/other content of the django.newforms is not enough to completely |
| 4 | satisfy all web design needs. So sometimes it is better to customize your forms completely. |
| 5 | |
| 6 | Using templates to render output as HTML or XML is straighforward and uses less code then as_table() counterpart |
| 7 | implemented now in the core newforms, so I hope technique explained here will be helpful. |
| 8 | |
| 9 | The above example has been crated specifically to mark required fields with red asterisk. |
| 10 | In fact all you need to do to use this, is to add 3 small files to your project, and replace |
| 11 | forms.Form to TemplatedForm class. Step by step explanations: |
| 12 | |
| 13 | 1. Create file in your project: |
| 14 | |
| 15 | yourproject/utils/newforms.py: |
| 16 | {{{ |
| 17 | #!python |
| 18 | |
| 19 | from django import newforms as forms |
| 20 | from django.newforms.forms import BoundField |
| 21 | from django.template import Context, loader |
| 22 | |
| 23 | class TemplatedForm(forms.Form): |
| 24 | def output_via_template(self): |
| 25 | "Helper function for fieldsting fields data from form." |
| 26 | bound_fields = [] |
| 27 | for name, field in self.fields.items(): |
| 28 | bf = BoundField(self, field, name) |
| 29 | bound_fields.append(bf) |
| 30 | |
| 31 | c = Context(dict(form = self, bound_fields = bound_fields)) |
| 32 | t = loader.get_template('newforms/form.html') |
| 33 | return t.render(c) |
| 34 | |
| 35 | def __str__(self): |
| 36 | return self.output_via_template() |
| 37 | }}} |
| 38 | |
| 39 | 2. Create HTML templates, here is very simple template form form and field: |
| 40 | |
| 41 | file: templates/newforms/form.html |
| 42 | {{{ |
| 43 | #!html |
| 44 | {% for field in bound_fields %} |
| 45 | {% include "newforms/field.html" %} |
| 46 | {% endfor %} |
| 47 | }}} |
| 48 | |
| 49 | file: templates/newforms/field.html |
| 50 | {{{ |
| 51 | <tr{% if field.errors %} class="errors" {% endif%}> |
| 52 | <th> |
| 53 | <label for="id_{{ field.name }}">{{ field.label }}{% if field.field.required %}<span class="required">*</span>{% endif %}:</label> |
| 54 | </th> |
| 55 | <td> |
| 56 | {{ field }} |
| 57 | {% if field.errors %}{{ field.errors }}{% endif %} |
| 58 | {% if field.help_text %} |
| 59 | <p class="helptext">({{ field.help_text }})</p> |
| 60 | {% endif %} |
| 61 | </td> |
| 62 | </tr> |
| 63 | }}} |
| 64 | |
| 65 | |
| 66 | Example of usage from view.py: |
| 67 | file: myproject/myapp/myview.py |
| 68 | {{{ |
| 69 | #!py |
| 70 | class PersonalInfoForm(TemplatedForm): |
| 71 | school_or_institution = forms.CharField(max_length=100,required=False) |
| 72 | first_name = forms.CharField(max_length=100,required=False) |
| 73 | last_name = forms.CharField(max_length=100,required=False) |
| 74 | email = forms.EmailField() |
| 75 | personal_website_url = forms.CharField(max_length=100,required=False) |
| 76 | button = forms.CharField(required=False,widget=forms.HiddenInput) |
| 77 | }}} |
| 78 | |