如何在Django模板中自定义单选按钮的显示?

时间:2018-02-22 21:59:03

标签: html django radio-button

在我的forms.py中,我有这个,其中supbplansTuple是一个元组元组:

class RegisterForm(UserCreationForm):
    subChoices= forms.ChoiceField(label=_("Choose plan"), widget=forms.RadioSelect, choices=subPlansTuple)

subplansTuple看起来像这样:

(("plan_1234","$5 a month"),("plan_2345","$10 a month"))

register.html有这个:

<form id="register-form" name="regForm" method="post">
    {% csrf_token %}
    {% for field in registration_form %}
        <p>{{ field }}</p>  
    {% endfor %}
</form>

问题是,Django会像这样显示单选按钮小部件:

<p></p>
<ul id="id_subChoices">
  <li>
    <label for="id_subChoices_0"><input id="id_subChoices_0" name="subChoices" type="radio" value="plan_1234" required=""> $5 a month</label>
  </li>
  <li>
    <label for="id_subChoices_1"><input id="id_subChoices_1" name="subChoices" type="radio" value="plan_2345" required=""> $10 a month</label>
  </li>
</ul>
<p></p>

我不希望单选按钮以这种方式显示。如何自定义HTML,可能看起来像Boostrap's inline radio buttons

3 个答案:

答案 0 :(得分:1)

在Django <1.11中,您应该编写一个自定义的小部件渲染,您可以在StackOverflow的不同文章中找到其他解决方案。

我不希望单选按钮以这种方式显示。如何自定义HTML,也许看起来像Boostrap的嵌入式单选按钮。

好吧,最后的代码很简单,您必须编写一个小类:

class SwitchRenderer(RadioFieldRenderer):
    outer_html = u'{content}'
    inner_html = u'{choice_value}{sub_widgets}'

然后在您的小部件上使用此类作为渲染器。

下面的示例是另一个可以提供帮助的用例。

Django版本1.9.x,我需要实现一个单选按钮,例如:https://codepen.io/JiveDig/pen/jbdJXR/

.switch-field {
	display: flex;
	margin-bottom: 36px;
	overflow: hidden;
}

.switch-field input {
	position: absolute !important;
	clip: rect(0, 0, 0, 0);
	height: 1px;
	width: 1px;
	border: 0;
	overflow: hidden;
}

.switch-field label {
	background-color: #e4e4e4;
	color: rgba(0, 0, 0, 0.6);
	font-size: 14px;
	line-height: 1;
	text-align: center;
	padding: 8px 16px;
	margin-right: -1px;
	border: 1px solid rgba(0, 0, 0, 0.2);
	box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.3), 0 1px rgba(255, 255, 255, 0.1);
	transition: all 0.1s ease-in-out;
}

.switch-field label:hover {
	cursor: pointer;
}

.switch-field input:checked + label {
	background-color: #a5dc86;
	box-shadow: none;
}

.switch-field label:first-of-type {
	border-radius: 4px 0 0 4px;
}

.switch-field label:last-of-type {
	border-radius: 0 4px 4px 0;
}

/* This is just for CodePen. */

.form {
	max-width: 600px;
	font-family: "Lucida Grande", Tahoma, Verdana, sans-serif;
	font-weight: normal;
	line-height: 1.625;
	margin: 8px auto;
	padding: 16px;
}

h2 {
	font-size: 18px;
	margin-bottom: 8px;
}
<form class="form">
	<h2>Is this awesome?</h2>
	<div class="switch-field">
		<input type="radio" id="radio-one" name="switch-one" value="yes" checked/>
		<label for="radio-one">Yes</label>
		<input type="radio" id="radio-two" name="switch-one" value="no" />
		<label for="radio-two">No</label>
	</div>
</form>

为此,我扩展了一些类:

class SwitchChoiceInput(RadioChoiceInput):
    def render(self, name=None, value=None, attrs=None, choices=()):
        if self.id_for_label:
            label_for = format_html(' for="{}"', self.id_for_label)
        else:
            label_for = ''
        attrs = dict(self.attrs, **attrs) if attrs else self.attrs
        return format_html(
            u'{} <label{}>{}</label>', self.tag(attrs), label_for, self.choice_label
        )


class SwitchRenderer(RadioFieldRenderer):
    choice_input_class = SwitchChoiceInput
    outer_html = u'{content}'
    inner_html = u'{choice_value}{sub_widgets}'

最后,在表单中,我使用了创建的渲染器:

field_switch = NullBoleanField(widget=RadioSelect(
                                          choices=[(True, 'Yes') (False, 'No')],
                                          renderer=SwitchRenderer))

我希望该解决方案可以帮助像我这样的人找到这篇文章。

答案 1 :(得分:1)

您的字段对象具有允许您单独呈现输入的属性,因此在模板中您可以使用仅呈现字段标签的 {{field.tag}} 并且在顶部您可以放置​​标签并在标签内用于放置输入 ID {{field.id_for_label}} 的属性。这样:

<form action="" method="post">
    {% csrf_token %}
    {% for field in registration_form %}
        <label for="{{field.id_for_label}}">{{field.choice_label}}</label>
        {{field.tag}}
    {% endfor %}
</form>

然后我们可以通过类用css自定义,使用浏览器在源代码中查看它们的类,或者通过RadioButton类的attrs属性在forms类内部定义类并使用它在 css 库中,一切由您决定。 https://docs.djangoproject.com/en/3.1/ref/forms/widgets/#radioselect

答案 2 :(得分:0)

在Django 1.11+中,表单小部件呈现是使用模板系统完成的,因此您可以覆盖&#34; django / forms / widgets / radio.html&#34;,例如。

但是,我建议使用django-crispy-forms。它确实有助于控制表单的呈现方式。