Django Model表单:如何更改字段的html

时间:2015-12-10 20:50:08

标签: django django-forms

我的目标第一:

这是Django的输出:

<div class="form-group ">
    <label>Statut:</label>
    <label for="id_statut" class="sr-only">Statut:</label>
    <ul id="id_statut">
        <li><label for="id_statut_0"><input class="form-control" id="id_statut_0" name="statut" title="Statut:" type="radio" value="1"> Marié(e)</label></li>
        <li><label for="id_statut_1"><input class="form-control" id="id_statut_1" name="statut" title="Statut:" type="radio" value="0" checked="checked"> Célibataire</label></li>
        <li><label for="id_statut_2"><input class="form-control" id="id_statut_2" name="statut" title="Statut:" type="radio" value="2"> Divorcé(e)</label></li>
    </ul>
</div>

以下是我需要格式化的方法:

<div class="form-group">
    <label>Statut:</label>
    <div class="radio">
        <label>
            <input type="radio" name="statut" id="id_statut_0" value="option1" checked="checked">Marié(e)
        </label>
    </div>
    <div class="radio">
        <label>
            <input type="radio" name="statut" id="id_statut_1" value="option2">Célibataire
        </label>
    </div>
    <div class="radio">
        <label>
            <input type="radio" name="statut" id="id_statut_2" value="option3">Divorcé(e)
        </label>
    </div>
</div>

我的配置:

这是我的模特:

@python_2_unicode_compatible
class Personne(BaseModel):
    STATUT_CELIBATAIRE = u'0'
    STATUT_MARIE = u'1'
    STATUT_DIVORCE = u'2'
    TAB_STATUT = {STATUT_CELIBATAIRE: _(u'Single'),
                  STATUT_MARIE: _(u'Married'),
                  STATUT_DIVORCE: _(u'Divorced'), }
    statut = models.CharField(max_length=1,
                              choices=[(a, b) for a, b in
                                       list(TAB_STATUT.items())],
                              default=STATUT_CELIBATAIRE)

这是我的表格:

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=forms.RadioSelect(attrs={
            'title': _(u'Statut:'),
            'class': 'form-control'}))

请注意,我尝试添加“class”属性。

这是我的模板:

{% for field in form %}
    <div class="form-group {% if field.errors %}has-error{% endif %}">
        <label>{{ field.label }}</label>
        <label for="{{ field.auto_id }}"
               class="sr-only">{{ field.label }}
        </label>
        {{ field }}
    </div>
    {% if field.errors %}
    <div class="form-group">
        <div class="alert alert-danger" role="alert">
        {% for error in field.errors %}
            <span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
            <span class="sr-only">{{ error }}</span>
            {{ error }}
        {% endfor %}
        </div>
    </div>
    {% endif %}
    {{ field.help_text }}
{% endfor %}

1 个答案:

答案 0 :(得分:0)

两个主要选项是:

  1. 在模板中标记整个内容(您可以从field对象获取所有需要的信息)或
  2. 继承RadioSelect并为自己创建一个新的小部件。
  3. 这里第二个选择更短。

    RadioSelect的定义如下:

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

    所有魔法都在ChoiceFieldRendererRadioFieldRenderer的父类)中:

    @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>'
    
        ...
    

    所以您只需更改新渲染器的outer_htmlinner_html代码。

    你可以这样做:

    # 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'}))
    

    输出我的模板:

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