django radioselect渲染到表

时间:2011-02-16 15:48:33

标签: django django-forms django-widget

我想将django表单widget radioselect渲染到表而不是ul列表中。第一行中有标签,第二行下面有单选按钮。每个按钮一个单元格。 e.g。

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

我查看了默认的selectradio小部件,但渲染函数看起来很复杂,调用许多不同的类来完成渲染的每个部分。

有没有人有任何关于如何做到这一点或可以提供简单解决方案的例子?

4 个答案:

答案 0 :(得分:7)

只是为了填写更多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)”

我希望有所帮助!

答案 1 :(得分:2)

您需要继承 django.forms.widgets.RadioFieldRenderer 并覆盖它的渲染方法。 然后在您的表单中,在声明您的字段时指定窗口小部件的自定义渲染器

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

答案 2 :(得分:0)

您也可以使用django-uni-form并使用div而不是表格。

答案 3 :(得分: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源代码,仅略微修改以显示每个方法中应用简单的自定义。