4

Django フォーム ウィジェット radioselect を ul リストではなくテーブルにレンダリングしたいと考えています。最初の行にラベルがあり、2 行目にラジオ ボタンがあります。ボタンごとに 1 つのセル。例えば

-------------------------------
| label 1 | label 2 | label 3 |
-------------------------------
|   O     |    O    |    O    |
-------------------------------

デフォルトの selectradio ウィジェットを見てきましたが、レンダリング機能は非常に複雑に見え、レンダリングの各部分を実行するために多くの異なるクラスを呼び出します。

これを行う方法の例や簡単な解決策を提供できる人はいますか?

4

4 に答える 4

8

BéresBotondの答えをもう少し埋めるために

class MyForm(forms.ModelForm):
    my_field = forms.TypedChoiceField(choices=some_choices,
                                      label=u"bla",
                                      widget=forms.RadioSelect(renderer=MyCustomRenderer))

カスタム レンダラーは次のようになります。

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

class MyCustomRenderer( RadioFieldRenderer ):
    def render( self ):
        """Outputs a series of <td></td> fields for this set of radio fields."""
        return( mark_safe( u''.join( [ u'<td>%s</td>' % force_unicode(w.tag()) for w in self ] )))

この場合、横にラジオ ボックスの名前が必要なかったので、"force_unicode(w.tag())" を使用しています。横に名前が必要な場合は、オブジェクトを直接 "force_unicode( w)"

それが役立つことを願っています!

于 2011-07-24T19:12:13.947 に答える
2

django.forms.widgets.RadioFieldRendererをサブクラス化し、そのrenderメソッドをオーバーライドする必要があります。次に、フォームでフィールドを宣言するときに、ウィジェットのカスタム レンダラーを指定します。

class MyForm(forms.ModelForm):
    my_field = forms.TypedChoiceField(choices=some_choices,
                                      label=u"bla",
                                      widget=forms.RadioSelect(renderer=MyCustomRenderer))
于 2011-02-16T16:18:03.640 に答える
0

また、 django-uni-formを使用して、テーブルの代わりにdivを使用することもできます。

于 2011-03-29T06:33:23.513 に答える
0

入力要素をさらにカスタマイズする必要がある場合は、カスタム レンダラーの choice_input_class 属性を上書きします。

from django.forms.widgets import RadioChoiceInput, RadioFieldRenderer   
from django.utils.safestring import mark_safe
from django.utils.html import format_html

class MyCustomRenderer( RadioFieldRenderer ):
    choice_input_class = MyCustomInputClass

class MyCustomInputClass(RadioChoiceInput):
    def render(self, name=None, value=None, attrs=None, choices=()):
        # Generate outer label, insert a custom div
        output = format_html('''
            <div id="{}"></div>
        ''', self.choice_label)
        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('<label{}>{} {}</label>',
                           label_for, self.tag(attrs), output)

    def tag(self, attrs=None):
        # Generate the customized input element.
        attrs = attrs or self.attrs
        final_attrs = dict(attrs, type=self.input_type, name=self.name, value=self.choice_value)
        if self.is_checked():
            final_attrs['checked'] = 'checked'
        return format_html('<input{} class="my_custom_class" />', flatatt(final_attrs))

これらrender()tag()メソッドは 1.9 のソース コードからのもので、それぞれに簡単なカスタマイズを適用することを示すためにわずかに変更されています。

于 2017-02-13T05:03:15.973 に答える