【问题标题】:Overriding render of RadioSelect in django forms gives unexpected results在 django 表单中覆盖 RadioSelect 的渲染会产生意想不到的结果
【发布时间】:2018-07-11 15:57:46
【问题描述】:

我想在 django 中覆盖 RadioSelect 的渲染。 (我为复选框做了类似的事情,我希望两者看起来一样)。一般的工作流程是编写一个自定义渲染器,然后在 ChoiceInput 中更改渲染,但是当我复制现有代码并运行它时,html 输出不安全,并且显示了转义的 html 字符串。这没有任何意义,因为除了更改名称之外,我还没有对课程进行任何更改:

在我的 widgets.py 中:

class ButtonRadioFieldRenderer(ChoiceFieldRenderer):
    choice_input_class = OtherRadioChoiceInput


class OtherRadioChoiceInput(OtherChoiceInput):
    input_type = 'radio'

    def __init__(self, *args, **kwargs):
        super(OtherRadioChoiceInput, self).__init__(*args, **kwargs)
        self.value = force_text(self.value)


@html_safe
@python_2_unicode_compatible
class OtherChoiceInput(SubWidget):
    """
    An object used by ChoiceFieldRenderer that represents a single
    <input type='$input_type'>.
    """
    input_type = None  # Subclasses must define this

    def __init__(self, name, value, attrs, choice, index):
        self.name = name
        self.value = value
        self.attrs = attrs
        self.choice_value = force_text(choice[0])
        self.choice_label = force_text(choice[1])
        self.index = index
        if 'id' in self.attrs:
            self.attrs['id'] += "_%d" % self.index

    def __str__(self):
        return self.render()

    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(
            '<label{}>{} {}</label>', label_for, self.tag(attrs), self.choice_label
        )

    def is_checked(self):
        return self.value == self.choice_value

    def tag(self, attrs=None):
        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{} />', flatatt(final_attrs))

    @property
    def id_for_label(self):
        return self.attrs.get('id', '')

在我的 forms.py 中:

DELIMITER_CHOICES = [
    ('space', ugettext_lazy("space")),
    ('underscore', "_"),
    ]

class SingleDelimiterForm(forms.Form):

    delimiter = forms.ChoiceField(initial=0, widget=forms.RadioSelect(renderer=ButtonRadioFieldRenderer), choices=DELIMITER_CHOICES)

我所做的唯一更改是将“Other”和“Button”放在已经存在的类前面,并且代码不再运行。如果我将 OtherChoiceInput 更改为 ChoiceInput 代码正在工作。 (最后我只想给标签加一个类……)

【问题讨论】:

  • 我正在运行 Django 1.8,这是来自 django 1.8 的纯代码,仅对类进行了名称修改。

标签: django forms radio-button widget


【解决方案1】:

我需要 unicode 字符串才能使代码正常工作,因此 from __future__ import unicode_literals 解决了这个问题。我仍然觉得这个错误非常令人困惑。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-28
    • 2021-12-28
    • 2019-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多