热门标签:
Q:

在Django表单中,如何呈现单选按钮,以便在页面上分离选择?

我有一个Django表单,带有两个选择单选按钮元素。 我希望表单或多或少像这样呈现:

( ) I prefer beer
     The last sporting event I attended was: [           ]
     My favorite NASCAR driver is:           [           ]

( ) I prefer wine
     The last opera/play I attended was:     [           ]
     My favorite author is:                  [           ]

换句话说,我想拆分两个单选按钮选择。 我该怎么做? 使用默认的form.as_table渲染,选择被绘制在彼此旁边,我不想要。

(向NASCAR和歌剧爱好者道歉。)

原网址
A:

我做了一点挖掘,并在thissimilar post的答案中找到了一个线索,该帖子指向django-users中有点过时的帖子。

中的as_widget()方法中借用一些代码forms.py我创建了一个方法,我可以添加到我的表单中,以便检索RadioSelect小部件呈现为HTML的选择。

class MyForm(forms.Form):
    MY_CHOICES = (
        ('opt0', 'Option zero'),
        ('opt1', 'Option one'),
    )
    myfield = forms.ChoiceField(widget=forms.RadioSelect, choices=MY_CHOICES)

    def myfield_choices(self):
        """
        Returns myfield's widget's default renderer, which can be used to 
            render the choices of a RadioSelect widget.
        """
        field = self['myfield']
        widget = field.field.widget

        attrs = {}
        auto_id = field.auto_id
        if auto_id and 'id' not in widget.attrs:
            attrs['id'] = auto_id

        name = field.html_name

        return widget.get_renderer(name, field.value(), attrs=attrs)

然后在模板中,您可以访问单个单选按钮选择,如下所示:

<ul>
    <li>
        {{ myform.myfield_choices.0 }}
        My custom HTML that goes with choice 0 
    </li>
    <li>
        {{ myform.myfield_choices.1 }}
        Different HTML that goes with choice 1 
    </li>
</ul>

{% for choice in myform.myfield_choices %}
    <div>
        {{ choice }}
    </div>
{% endfor %}

我很确定这是个坏主意。 随着django的发展,它可能会在某个时候停止工作。 它通过从as_widget()复制代码来违反DRY。 (TBH,我没有花时间完全理解as_widget的代码)我只将其用作临时黑客。 也许有一个更好的方法,涉及自定义模板标签。 如果是这样,请告诉我。

所有回答

共 1 条

author avatar

RadioSelect控件将默认将其输出呈现为无序列表。

#forms.py
BEER = 0
WINE = 1
PREFERRED_DRINK_CHOICES = (
    (BEER, 'Beer'),
    (WINE, 'Wine'),
)

class DrinkForm(forms.Form):
    preferred_drink = forms.ChoiceField(choices=PREFERRED_DRINK_CHOICES,
                                        widget=forms.RadioSelect())

#views.py
def test(request):
    form = DrinkForm(request.POST or None)
    if request.method == 'POST':
        if form.is_valid():
            print 'form was valid'
    return render_to_response('test.html', {'form' : form},
        context_instance=RequestContext(request))

#test.html
<form action="." method="post" enctype="multipart/form-data">
    <ul>
        <li>
            {{ form.name.label_tag }}
            {{ form.name }}
            {{ form.name.errors }}
        </li>
        <li>
            {{ form.email.label_tag }}
            {{ form.email }}
            {{ form.email.errors }}
        </li>
        <li>
            {{ form.preferred_drink.label_tag }}
            {{ form.preferred_drink }}
            {{ form.preferred_drink.errors }}
        </li>
        <li>
        <input type="submit" value="Submit" />
        </li>
    </ul>
</form>

会输出:

<form enctype="multipart/form-data" method="post" action=".">
    <ul>
    <li>
            <label for="id_name">Name</label>
            <input type="text" maxlength="50" name="name" id="id_name">
    </li>
    <li>
        <label for="id_email">Email</label>
        <input type="text" id="id_email" name="email">
    </li>
    <li>
        <label for="id_preferred_drink_0">Preferred drink</label>
        <ul>
                    <li>
                        <label for="id_preferred_drink_0">
                            <input type="radio" name="preferred_drink" value="0" id="id_preferred_drink_0"> Beer</label>
                    </li>
                    <li>
                        <label for="id_preferred_drink_1"><input type="radio" name="preferred_drink" value="1" id="id_preferred_drink_1"> Wine</label>
                    </li>
                </ul>
        </li>
    <li>
        <input type="submit" value="Submit">
    </li>
    </ul>
</form>

这将使每个无线电选择在自己的线路上. 你可能需要添加一些CSS来获得你想要的渲染方式,但这应该得到你需要的结构。 当然,你可以用手工快速编写HTML...

<form action="." method="post">
    <ul>
        {{ form.as_ul }}
        <li>
            <input type="submit" value="Submit" />
        </li>
    </ul>
</form>

...但我更喜欢手工编写我的HTML。

相似问题