[Fixed]-Django Model forms: how change html of a field

1👍

Two main options are:

  1. mark up the whole thing in a template (you can get all the needed information form the field object) or
  2. subclass the RadioSelect and make yourself a new widget.

Here the second choice is shorter.

RadioSelect is defined like this:

class RadioSelect(RendererMixin, Select):
    renderer = RadioFieldRenderer
    _empty_value = ''

And all the magic is in the ChoiceFieldRenderer (parent class of the RadioFieldRenderer):

@html_safe
@python_2_unicode_compatible
class ChoiceFieldRenderer(object):
    """
    An object used by RadioSelect to enable customization of radio widgets.
    """

    choice_input_class = None
    outer_html = '<ul{id_attr}>{content}</ul>'
    inner_html = '<li>{choice_value}{sub_widgets}</li>'

    ...

So all you need is to change outer_html and inner_html code for a new renderer.

You can do it this way:

# coding: utf-8
from django import forms
from django.forms.widgets import RadioFieldRenderer
from django.utils.translation import ugettext_lazy as _

from .models import Personne


class MyRadioFieldRenderer(RadioFieldRenderer):
    outer_html = '{content}'
    inner_html = '<div class="radio">{choice_value}{sub_widgets}</div>'


class MyRadioSelect(forms.RadioSelect):
    renderer = MyRadioFieldRenderer


class ProfileForm(forms.ModelForm):
    class Meta:
        model = Personne
        fields = ['statut']

    statut = forms.TypedChoiceField(
        label=_(u'Statut:'),
        choices=[(k, Personne.TAB_STATUT[k])
                 for k in Personne.TAB_STATUT],
        widget=MyRadioSelect(attrs={
            'title': _(u'Statut:'),
            'class': 'form-control'}))

Output I’ve got with your template:

<div class="form-group ">
    <label>Statut:</label>
    <div class="radio">
        <label for="id_statut_0"><input class="form-control"
            id="id_statut_0" name="statut" title="Statut:" type="radio" value="1" />
            Married</label>
    </div>
    <div class="radio">
        <label for="id_statut_1"><input class="form-control"
            id="id_statut_1" name="statut" title="Statut:" type="radio" value="0" />
            Single</label>
    </div>
    <div class="radio">
        <label for="id_statut_2"><input class="form-control"
            id="id_statut_2" name="statut" title="Statut:" type="radio" value="2" />
            Divorced</label>
    </div>
</div>
👤twil

Leave a comment