8

そのため、 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>

要約すると、 と があるクラス (ラジオ) 内のラジオ ボタンが必要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>

リスト部分を除いて、まさに私が欲しいものです。だから私はそれをループしてみました。これにより、異なる形式のラベルが得られます。

{% for item in profile_form.notify_new_friends %}
    {{ item }}
{% endfor %}

それは私に与える:

<label><input type="radio" name="notify_new_friends" value="0" /> Immediately</label>
<label><input type="radio" name="notify_new_friends" value="1" /> Never</label>

したがって、ここでの問題は、使用を停止し、すべてをラップするため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 }}

これを適切にレンダリングする方法を知っている人はいますか!?

参考までに、これは私のforms.pyです:

self.fields['notify_new_friends'] = forms.ChoiceField(label='Notify when new friends join', widget=forms.RadioSelect, choices=NOTIFICATION_CHOICES)
4

5 に答える 5

10

私のコードでは、ウィジェットを

forms.RadioSelect

forms.RadioSelect(attrs={'id': 'value'})

結果のtag値にid、アイテムのインデックスが追加された属性が魔法のように含まれます。使用する場合

{% for radio in form.foo %}
    <li>
        {{ radio }}
    </li>
{% endfor %}

を取得する形式で、 をlabelラップしinputます。より従来型のinputlabelに が必要な場合は、次のようにする必要があります。

{% for radio in form.value %}
    <li>
        {{ radio.tag }}
        <label for="value_{{ forloop.counter0 }}">{{ radio.choice_label }}</label>
    </li>
{% endfor %}
于 2013-02-14T11:39:46.007 に答える
3

残念ながら、これは必要以上に複雑です。少なくとも 2 つのクラスをオーバーライドする必要があるようです:RadioRendererRadioInput. 以下は、開始するのに役立つはずですが、少し調整する必要がある場合があります。

まず、カスタム ラジオ ボタン入力ウィジェットを作成します。<label><input /></label>render メソッドをオーバーライドする唯一の目的は、Django が ( ) を強制する厄介な構造を取り除くことです<label /><input />

class CustomRadioInput(RadioInput):
    def render(self, name=None, value=None, attrs=None, choices=()):
        name = name or self.name
        value = value or self.value
        attrs = attrs or self.attrs
        if 'id' in self.attrs:
            label_for = ' for="%s_%s"' % (self.attrs['id'], self.index)
        else:
            label_for = ''
            choice_label = conditional_escape(force_unicode(self.choice_label))
            return mark_safe(u'%s<label%s>%s</label>' % (self.tag(), label_for, choice_label))

RadioRenderer次に、次のことを行うためにオーバーライドする必要があります。

  1. カスタム ラジオ入力ウィジェットの使用を強制する
  2. <li>すべての入力フィールドの<ul>ラップとすべての入力フィールドのラップを削除します。

これらの行に沿って何かを行う必要があります:

class RadioCustomRenderer(RadioFieldRenderer):
    def __iter__(self):
        for i, choice in enumerate(self.choices):
            yield CustomRadioInput(self.name, self.value, self.attrs.copy(), choice, i)

    def __getitem__(self, idx):
        choice = self.choices[idx]
        return CustomRadioInput(self.name, self.value, self.attrs.copy(), choice, idx)

    def render(self):
        return mark_safe(u'%s' % u'\n'.join([u'%s' % force_unicode(w) for w in self]))

最後に、Django にカスタム レンダラーを使用するように指示します。

notify_new_friends = forms.ChoiceField(label='Notify when new friends join', widget=forms.RadioSelect(renderer=RadioCustomRenderer), choices=NOTIFICATION_CHOICES)

心に留めておいてください:これは、ラジオボタンを囲んで一緒に出力<td>するようになったため、テンプレートでそれを囲むようにテーブルを作成する必要があります。

<table>
  <tr>
    <td><label for="{{field.auto_id}}">{{field.label}}</label></td>
    <td>{{ field.errors }} {{field}}</td>
  </tr>
</table>
于 2013-04-11T14:42:18.970 に答える
1

これは良い方法ではないように思われるので、生成されたコードを 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();

これにより、次のようになりました。

<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>

に:

<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>

私のjQuery UIスタイリングはうまくいきます。

于 2012-07-19T10:09:28.467 に答える
0
Try like this ,  I got it..

from django.forms.widgets import RadioFieldRenderer
from django.utils.encoding import force_unicode
from django.utils.safestring import mark_safe


class RadioCustomRenderer( RadioFieldRenderer ):
    def render( self ):
        return  mark_safe(u'%s' % u'\n'.join([u'%s'  % force_unicode(w) for w in self]))

in form

widgets = {
            'validity': forms.RadioSelect(renderer=RadioCustomRenderer),
        }
于 2013-03-31T07:14:15.093 に答える