| | 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 | |