如何在Django中呈现单个单选按钮选项?

时间:2012-04-19 21:34:58

标签: django django-templates

如果我的模型包含带有RadioSelect小部件的ChoiceField,我该如何在模板中单独渲染单选按钮?

假设我正在构建一个Web应用程序,允许公司的新员工在桌面上选择他们想要的计算机。这是相关模型:

class ComputerOrder(forms.Form):
    name = forms.CharField(max_length=50)
    office_address = forms.Charfield(max_length=75)
    pc_type = forms.ChoiceField(widget=RadioSelect(), choices=[(1, 'Mac'), (2, 'PC')])

在模板上,如何渲染只是 Mac选择按钮?如果我这样做,它会呈现所有选择:

{{ form.pc_type  }}

我有点天真地试过这个,但没有输出:

{{ form.pc_type.0 }}

(我在SO上发现了一些类似的问题:

In a Django form, how do I render a radio button so that the choices are separated on the page?
Django Forms: How to iterate over a Choices of a field in Django form

但我觉得他们没有好的答案。有没有办法复活旧问题?)

4 个答案:

答案 0 :(得分:44)

Django 1.4 + allows you to iterate关于RadioSelect中的选项,以及

{% for choice in form.pc_type %}
  {{ choice.choice_label }}
  <span class="radio">{{ choice.tag }}</span>
{% endfor %}

我不确定此更改是否允许您使用您描述的语法({{ form.pc_type.0 }}) - 如果没有,您可以使用上面的for循环和{{{}之类的标记来解决此限制{1}}。

如果你被绑在Django&lt; 1.4,您可以按照建议覆盖{% if forloop.counter0 == 0 %}方法,或者使用稍微更详细但更简单的选项来自己在模板中构建表单字段:

render()

{% for choice in form.pc_type.field.choices %} <input name='{{ form.pc_type.name }}' id='{{ form.pc_type.auto_id }}_{{ forloop.counter0 }}' type='radio' value='{{ choice.0 }}' {% if not form.is_bound %}{% ifequal form.pc_type.field.initial choice.0 %} checked='checked' {% endifequal %} {% else %}{% ifequal form.pc_type.data choice.0 %} checked='checked' {% endifequal %}{% endif %}/> <label for='{{ form.pc_type.auto_id }}_{{ forloop.counter0 }}'>{{ choice.1 }}</label> {% endfor %} choice.0choice.1二元组中的第一项和第二项

答案 1 :(得分:6)

单个无线电输入的呈现由RadioSelect小部件的render方法处理。如果您想要一个不同的呈现,子类RadioSelect,请相应地更改render方法,然后使用您的子类作为字段的小部件。

答案 2 :(得分:4)

我认为简单地看一下选择字段的for循环中可用的内容将告诉他们需要知道什么。例如,我需要值来设置围绕选项范围的类(对于颜色等):

<div>
    {% for radio_input in form.role %}
        {# Skip the empty value #}
        {% if radio_input.choice_value %}
            <span class="user-level {{ radio_input.choice_value }}">{{ radio_input }}</span>
        {% endif %}
    {% endfor %}
</div>

您可以看到有几个属性可以让您不必使用序数。

PyCharm Debugging Inside a Template

答案 3 :(得分:2)

在Django 2.0+中,您可以子类forms.RadioSelect并“简单地”指定用于渲染无线电字段的模板:

class SlimRadioSelect(forms.RadioSelect):
    template_name = 'includes/slim_radio.html'

其中slim_radio.html包含default RadioSelect widget使用的template_nameoption_template_name的合并版本。

请注意,默认的RadioSelect窗口小部件模板是低级渲染,并且由高度分层的模板组成:包含很多,条件和循环逻辑标记。

packages/django/forms/templates/django/forms/widgets/input.html进行挖掘以获得所需的东西时,您会知道已经到达。

重写默认窗口小部件模板的另一个奇怪之处是,必须在项目通常可访问的模板路径中调用TemplatesSetting渲染器或子类won't be able to find slim_radio.html

要覆盖RadioSelect的仅本地模板路径查找:

  1. 'django.forms'添加到您的INSTALLED_APPS;

  2. FORM_RENDERER = 'django.forms.renderers.TemplatesSetting'添加到您的settings.py.

这一切似乎都比应做的难,但这就是框架。祝你好运。