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

2023-09-06 19:13:53 作者:下里巴人

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

I have a Django form with a two-choice radio button element. I want the form to render more or less like this:

换句话说,我想拆分两个单选按钮选项.我怎么做?使用默认的 form.as_table 渲染,我不想要的选项是相邻绘制的.

( ) 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: [ ]

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

In other words, I want to split up the two radio button choices. How do I do that? Using the default form.as_table rendering, the choices are drawn right next to each other which I don't want.

推荐答案

我做了一点挖掘,并在这个问题的答案中找到了线索类似的帖子 指向有点过时的 post in django-users.

解决方案

从 forms.py 我设计了一种方法,可以将其添加到我的表单中,以便检索呈现为 HTML 的 RadioSelect 小部件的选择.

I did a little digging, and found a lead in the answer to this similar post that points to a somewhat outdated post in django-users.

Borrowing some code from the as_widget() method in forms.py I fashioned a method that I could add to my form in order to retrieve the RadioSelect widget's choices rendered as 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)

Then in the template you can access individual radio button choices like so:

or 
{{ 选择 }}</div>{% endfor %}

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

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

I'm pretty sure this is a bad idea. It will likely stop working at some point as django evolves. It violates DRY by copying code from as_widget(). (TBH, I didn't take the time to fully understand the code from as_widget) I'm using it as a temporary hack only. Perhaps there is a better way that involves custom template tags. If so, please let me know.