| 1 | ============================================ |
| 2 | Writing (and using) a custom widget renderer |
| 3 | ============================================ |
| 4 | |
| 5 | It's possible to override a renderer for a specific widget by subclassing |
| 6 | it. A good example is the RadioSelect widget that, by default, outputs |
| 7 | a list of items. |
| 8 | |
| 9 | To override this behavior, we need to subclass the widget. In particular |
| 10 | its renderer function. For example, take this piece of code that can be |
| 11 | included in ``myproject/myapp/forms.py``: |
| 12 | |
| 13 | .. code-block:: python |
| 14 | from django.forms.widgets import RadioFieldRenderer, RadioSelect |
| 15 | from django.utils.encoding import StrAndUnicode, force_unicode |
| 16 | from django.utils.safestring import mark_safe |
| 17 | |
| 18 | class CustomRenderer(RadioFieldRenderer): |
| 19 | def render(self): |
| 20 | return mark_safe(u'\n%s\n' % u'\n'.join([u'<tr><td>%s</td></tr>' |
| 21 | % force_unicode(w) for w in self])) |
| 22 | |
| 23 | class CustomRadioSelect(RadioSelect): |
| 24 | renderer = CustomRenderer |
| 25 | |
| 26 | |
| 27 | You can then use the new widget like this: |
| 28 | |
| 29 | .. code-block:: python |
| 30 | class OSChoiceForm(forms.Form): |
| 31 | OS_CHOICES = ( |
| 32 | ('linux', 'Linux'), |
| 33 | ('windows', 'Windows'), |
| 34 | ('mac', 'Macintosh'), |
| 35 | ) |
| 36 | os = forms.ChoiceField(label='', widget=CustomRadioSelect, choices=OS_CHOICES ) |
| 37 | |
| 38 | And the form will be rendered as table rows instead of list items. |
| 39 | |