使用RadioSelect小部件自定义Django表单

olo*_*fom 7 django django-templates django-forms

所以我使用jQuery UI为单选按钮设置外观,但我不能让Django按照必须完成的方式呈现我的表单.

我需要这个结构:

<table>
    <tr>
        <td><label for="notify_new_friends">Notify when new friends join</label></td>
        <td class="radio">
            <input type="radio" name="notify_new_friends" id="notify_new_friends_immediately" value="1" checked="checked"/><label for="notify_new_friends_immediately">Immediately</label>
            <input type="radio" name="notify_new_friends" id="notify_new_friends_never" value="0"/><label for="notify_new_friends_never">Never</label>
        </td>
    </tr>
</table>
Run Code Online (Sandbox Code Playgroud)

总而言之,我需要一个类(无线电)中的单选按钮,它们有一个input和一个label for.

当我在模板中渲染表单时,{{ profile_form.notify_new_friends }}我得到以下内容:

<ul>
    <li><label for="id_notify_new_friends_0"><input type="radio" id="id_notify_new_friends_0" value="0" name="notify_new_friends" /> Immediately</label></li>
    <li><label for="id_notify_new_friends_1"><input type="radio" id="id_notify_new_friends_1" value="1" name="notify_new_friends" /> Never</label></li>
</ul>
Run Code Online (Sandbox Code Playgroud)

除了list-part之外,这正是我想要的.所以我尝试循环它,这给了我不同格式的标签:

{% for item in profile_form.notify_new_friends %}
    {{ item }}
{% endfor %}
Run Code Online (Sandbox Code Playgroud)

这给了我:

<label><input type="radio" name="notify_new_friends" value="0" /> Immediately</label>
<label><input type="radio" name="notify_new_friends" value="1" /> Never</label>
Run Code Online (Sandbox Code Playgroud)

所以这里的问题是它停止使用label for并开始使用仅label用于包装它.

我也尝试过做这样的事情,但之后labellabel_tag没有渲染任何东西.

{{ profile_form.notify_new_friends.0 }}
{{ profile_form.notify_new_friends.0.label_tag }}
{{ profile_form.notify_new_friends.0.label }}
Run Code Online (Sandbox Code Playgroud)

那么有谁知道我怎么能正确渲染这个!?

仅供参考,这是我的forms.py:

self.fields['notify_new_friends'] = forms.ChoiceField(label='Notify when new friends join', widget=forms.RadioSelect, choices=NOTIFICATION_CHOICES)
Run Code Online (Sandbox Code Playgroud)

pdc*_*pdc 7

在我的代码中,我发现从中更改小部件

forms.RadioSelect
Run Code Online (Sandbox Code Playgroud)

forms.RadioSelect(attrs={'id': 'value'})
Run Code Online (Sandbox Code Playgroud)

神奇地使结果tag值包含id具有附加项的索引的属性.如果你使用

{% for radio in form.foo %}
    <li>
        {{ radio }}
    </li>
{% endfor %}
Run Code Online (Sandbox Code Playgroud)

在形式上,你得到一个label包裹input.如果你想要更传统的input后续label,你需要这样做:

{% for radio in form.value %}
    <li>
        {{ radio.tag }}
        <label for="value_{{ forloop.counter0 }}">{{ radio.choice_label }}</label>
    </li>
{% endfor %}
Run Code Online (Sandbox Code Playgroud)


olo*_*fom 2

由于这似乎不是一个好方法,因此我选择使用 jQuery 重新排列生成的代码。

// First remove the ul and li tags
$('.radio ul').contents().unwrap();
$('.radio li').contents().unwrap();
// Then move the input to outside of the label
$('.radio > label > input').each(function() {
    $(this).parent().before(this);
});
// Then apply the jQuery UI buttonset
$( ".radio" ).buttonset();
Run Code Online (Sandbox Code Playgroud)

这使得它从:

<ul>
    <li><label for="id_notify_new_friends_0"><input type="radio" id="id_notify_new_friends_0" value="0" name="notify_new_friends" /> Immediately</label></li>
    <li><label for="id_notify_new_friends_1"><input type="radio" id="id_notify_new_friends_1" value="1" name="notify_new_friends" /> Never</label></li>
</ul>
Run Code Online (Sandbox Code Playgroud)

到:

<input type="radio" id="id_notify_new_friends_0" value="0" name="notify_new_friends" /><label for="id_notify_new_friends_0"> Immediately</label></li>
<input type="radio" id="id_notify_new_friends_1" value="1" name="notify_new_friends" /><label for="id_notify_new_friends_1"> Never</label></li>
Run Code Online (Sandbox Code Playgroud)

我的 jQuery UI 样式工作正常。

  • 我认为如果有可能在没有 javascript 的情况下做到这一点,我们应该避免 js...尤其是在页面加载方面 - 性能更差,SEO 更差。如果我们使用javascript来操作,它应该是动态操作,这会导致像交互这样的原因。 (3认同)