【问题标题】:Align radio buttons horizontally in django forms在 Django 表单中水平对齐单选按钮
【发布时间】:2011-08-21 14:08:12
【问题描述】:

我想水平对齐单选按钮。默认情况下,django 表单以垂直格式显示。

feature_type  = forms.TypedChoiceField(choices = formfields.FeatureType, widget = forms.RadioSelect)

是否有任何特殊参数可以传递给单选按钮对齐?

提前致谢

【问题讨论】:

  • 我认为这比 Django 更像是一个 CSS 问题。您也许可以向单选按钮添加一个类并说 float:left;在单选按钮类的 CSS 中。
  • 我用谷歌搜索了它,我发现了一个我无法使它工作的链接。 wikis.utexas.edu/display/~bm6432/…。我将尝试添加 css 并让您知道它是否修复。谢谢极客

标签: django forms radio-button alignment


【解决方案1】:

这就是RadioField 的行为。如果您希望它水平渲染,请创建一个水平渲染器,如下所示:

from django.utils.safestring import mark_safe

class HorizontalRadioRenderer(forms.RadioSelect.renderer):
  def render(self):
    return mark_safe(u'\n'.join([u'%s\n' % w for w in self]))


class ApprovalForm(forms.Form):
    approval = forms.ChoiceField(choices=APPROVAL_CHOICES,
                 initial=0,
                 widget=forms.RadioSelect(renderer=HorizontalRadioRenderer),
                                 )

【讨论】:

  • 嘿 lakshman,当我执行上面的代码时,它的错误 mark_safe 没有定义。如果您能提供帮助,那将是很大的帮助
  • 你应该从 Django.templates 导入它
  • 冷却它的工作正常 laxman。感谢您的帮助 :-) 我导入的 mark_safe 可以正常工作:from django.utils.safestring import mark_safe
  • 从 Django 1.11 开始,这给了我forms.RadioSelect.renderer 的错误:“type object 'RadioSelect' has no attribute 'renderer'”。
  • 我得到了同样的错误“类型对象'RadioSelect'没有属性'renderer'”。请帮助
【解决方案2】:

另一个出路是将ul->li列表的样式改为display:inline-block。你可以做这样的事情

 <style>
 ul#youelementId li{
  display: inline-block;
  }
</style>

希望这对下一位读者有所帮助。

【讨论】:

  • 在 Django 3.1.4 中对我有用的唯一方法
【解决方案3】:

我想出了一个替代解决方案。如果您使用引导程序呈现表单,则可以将 .form-check-inline 类添加到输入中,该字段将水平显示。下面列出的是显示我所描述内容的代码。我希望这可以帮助某人重新发明轮子。谢谢阅读。保重,度过美好的一天。

                feature_type = forms.MultipleChoiceField(
                required=False,
                ...
                widget=forms.CheckboxSelectMultiple(attrs={'class': 'form-check-inline'})
                )

【讨论】:

  • 这是一个非常好的和干净的解决方案。
  • 关闭required (=False) 的必要性是什么?
【解决方案4】:

在我的 Django 2.2.6 上面的解决方案上效果不佳,所以我在多次尝试后发布我的解决方案,并按照面包屑导航,直到使用 django 表单小部件模板。

我必须重写 2 个模板,继承我自己的小部件类,然后指向它。

修改后的默认django模板为:

  • django/forms/templates/django/forms/widgets/input_option.html
  • django/forms/templates/django/forms/widgets/multiple_input.html

现在他们是:

PROJECT_NAME/PROJECT_APP/templates/admin/horizo​​ntal_option.html

{% if widget.wrap_label %}<label{% if widget.attrs.id %} for="{{ widget.attrs.id }}"{% endif %} class="radio-inline">{% endif %}{% include "django/forms/widgets/input.html" %}{% if widget.wrap_label %} {{ widget.label }}</label>{% endif %}

PROJECT_NAME/PROJECT_APP/templates/admin/horizo​​ntal_radios.html

{% with id=widget.attrs.id %}<ul{% if id %} id="{{ id }}"{% endif %}{% if widget.attrs.class %} class="{{ widget.attrs.class }}"{% endif %}>{% for group, options, index in widget.optgroups %}{% if group %}
  <li>{{ group }}
    <ul{% if id %} id="{{ id }}_{{ index }}"{% endif %}>{% endif %}{% for option in options %}
    {% include option.template_name with widget=option %}{% endfor %}{% if group %}
  </ul></li>{% endif %}{% endfor %}
</ul>{% endwith %}
  • 第一个包含一个硬编码的类:class="radio-inline" at labels,默认情况下 Django 什么都没有
  • 第二个是无线电组的呈现,我删除了它们在内部 ul 标记中呈现的额外 HTML li 标记。

然后你需要创建自己的小部件类:

from django.forms import RadioSelect


class HorizontalRadioSelect(RadioSelect):
    template_name = 'admin/horizontal_radios.html'
    option_template_name = 'admin/horizontal_inputs.html'

最后,在我的例子中,我指出它覆盖了我的管理员中的 formfield_overrides 类属性。但我认为你也可以在你的模型中做到这一点:

    formfield_overrides = {
        models.BooleanField: {'widget': HorizontalRadioSelect(choices=[(True, "Yes"), (False, "No"), (None, "Unknown")],)},
    }

【讨论】:

  • 这是 Django 2.0+ 版本的正确解决方案,谢谢!
【解决方案5】:

修改后的表格。RadioSelect:

class HorizontalRadioSelect(forms.RadioSelect):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        css_style = 'style="display: inline-block; margin-right: 10px;"'

        self.renderer.inner_html = '<li ' + css_style + '>{choice_value}{sub_widgets}</li>'

使用 Django 1.10 的标准管理员在 Python 3.4 上工作

和 Django-Suit(http://djangosuit.com/)(它使用 Bootstrap 的 2 种样式)

尚未针对 Django-grappelli 进行测试。

【讨论】:

  • 此答案并不直接适用于用户提供的示例代码,因此无法回答他们的问题。
【解决方案6】:

根据the Django docs 'attrs' 是一个字典,其中包含要在呈现的小部件上设置的 HTML 属性。

考虑到这一点,一个简单的基于表单的解决方案将类似于以下内容:

feature_type  = forms.TypedChoiceField(
    choices = formfields.FeatureType,
    widget = forms.RadioSelect(attrs={
        'style': 'display: inline-block'
    })
)

【讨论】:

  • 没有“display”属性,应该是"style": "display: inline-block",这样就不行了。 display: inline-block 将应用于单选按钮,而不是 &lt;li&gt;
【解决方案7】:

实际上不需要在管理中覆盖小部件、模板或其他任何东西。至少从 2008 年开始(参见forms.css),最简单的方法是传递一个类属性inlineattrs={'class': 'inline'}

在自定义表单中,它可能如下所示:

field = forms.ChoiceField(choices=(('1', 'one'), ('2', 'two')),
                          widget=forms.RadioSelect(attrs={'class': 'inline'}))

……它对复选框的工作原理完全相同:

field = forms.MultipleChoiceField(choices=(('1', 'one'), ('2', 'two')),
                                  widget=forms.CheckboxSelectMultiple(attrs={'class': 'inline'}))

对于表单字段覆盖,它应该是相同的,通过 ModelAdmin formfield_overridesformfield_for_* 函数。

【讨论】:

    【解决方案8】:

    作为 renerer 为我提出此错误:

    AttributeError:类型对象“RadioSelect”没有属性“renderer”

    我想出了这个代码:

    <form method="post">
        {% csrf_token %}
        {% for question in form %}
            <p>{{ question.label }}: </p>
            {% for choice in question %}
                {{ choice }}
            {% endfor %}
        {% endfor %}
        <br><br>
        <button type="submit">
                submit
        </button>
    
    </form>
    

    【讨论】:

      【解决方案9】:

      您可以使用这种方法。在我看来,这是最简单的

      class YourAdminForm(forms.ModelForm):
      
          class Meta:
              model = models.YourModel
              widgets = {
                  "your_field": forms.RadioSelect(attrs={"class": "inline"}),
              }
      

      或者像这样定义你的字段

          your_field = forms.ChoiceField(
              choices=(...),
              widget=forms.RadioSelect(attrs={"class": "inline"}),
          )
      

      【讨论】:

        猜你喜欢
        • 2021-06-06
        • 2012-08-31
        • 2014-07-27
        • 2014-03-17
        • 2017-03-09
        • 1970-01-01
        • 1970-01-01
        • 2022-07-29
        • 2017-10-28
        相关资源
        最近更新 更多