Django 模型表单:如何更改 html 字段
Django Model forms: how change html of a field
我的第一个目标:
这是 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 %}
两个主要选项是:
- 在模板中标记整个内容(您可以从
field
对象中获取所有需要的信息)或
- 子类化
RadioSelect
并使自己成为一个新的小部件。
这里第二个选择比较短
RadioSelect
定义如下:
class RadioSelect(RendererMixin, Select):
renderer = RadioFieldRenderer
_empty_value = ''
所有的魔法都在 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>'
...
因此,您只需为新渲染器更改 outer_html
和 inner_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>
我的第一个目标:
这是 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 %}
两个主要选项是:
- 在模板中标记整个内容(您可以从
field
对象中获取所有需要的信息)或 - 子类化
RadioSelect
并使自己成为一个新的小部件。
这里第二个选择比较短
RadioSelect
定义如下:
class RadioSelect(RendererMixin, Select):
renderer = RadioFieldRenderer
_empty_value = ''
所有的魔法都在 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>'
...
因此,您只需为新渲染器更改 outer_html
和 inner_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>