Django 1.11水平选择字段

问题描述 投票:5回答:3

我刚从Django 1.10更新到1.11.1。在我的模板new_house_edit.html中,我有以下内容:

{{ form.rating }}

models.py包含以下内容:

class NewHouse(models.Model):
    rating = models.IntegerField(choices=(
                                    (1, "1"),
                                    (2, "2"),
                                    (3, "3"),
                                    (4, "4"),
                                    (5, "5"),
                                    ),
                                    default=3
                            )

forms.py我曾经有以下内容:

class HorizontalRadioRenderer(forms.RadioSelect.renderer):
    def render(self):
        return mark_safe(u'\n'.join([u'%s\n' % w for w in self]))

class NewHouseForm(forms.ModelForm):

    class Meta:
        model = NewHouse
        fields = (
                'rating',)
        widgets={
                "rating": forms.RadioSelect(renderer=HorizontalRadioRenderer),
                }

哪个给出了以下错误AttributeError: type object 'RadioSelect' has no attribute 'renderer'.我试图通过这样做解决它,这是行不通的:

class HorizontalRadioSelect(forms.RadioSelect):
    template_name = 'new_house_edit'


class NewHouseForm(forms.ModelForm):

    class Meta:
        model = NewHouse
        fields = (
                'rating',)
        widgets={
                "rating": "rating": forms.ChoiceField(widget=HorizontalRadioSelect, choices=(1, 2, 3, 4, 5)),
                }

我现在得到错误AttributeError: 'ChoiceField' object has no attribute 'use_required_attribute'。谁能帮我解决这个问题?

django
3个回答
10
投票

在第二个代码段中,您将表单字段对象传递给窗口小部件dict而不是窗口小部件对象。所以正确的代码如下:

class HorizontalRadioSelect(forms.RadioSelect):
    template_name = 'horizontal_select.html'


class NewHouseForm(forms.ModelForm):

    class Meta:
        model = NewHouse
        fields = (
                'rating',)
        widgets={
                "rating": HorizontalRadioSelect()
                }

在您的app目录中创建模板文件夹,并使用以下html添加horizo​​ntal_select.html。

{% with id=widget.attrs.id %}
    <ul{% if id %} id="{{ id }}"{% endif %}{% if widget.attrs.class %} class="{{ widget.attrs.class }}"{% endif %}>
        {% for group, options, index in widget.optgroups %}
            {% if group %}
                <li>{{ group }}
                <ul{% if id %} id="{{ id }}_{{ index }}"{% endif %}>
            {% endif %}
            {% for option in options %}
                <li style="display: inline-block">{% include option.template_name with widget=option %}</li>
            {% endfor %}
            {% if group %}
                </ul>
                </li>
            {% endif %}
        {% endfor %}
    </ul>
{% endwith %}

3
投票

我知道这是一个相当古老的问题但今天花了一些时间在各种线程中尝试不同的方法(从1.8升级到1.11之后)这是我的解决方案。

对于每个无线电组,在模板中定义以下内容(其中“radio_list”是字段的名称):

{% for radio in radio_list %}
    {{ radio }}
{% endfor %} 

这是最简单的。容易呃?您基本上可以应用任何您想要的样式。这一切都在RadioSelect部分的documentation中。

这个小故事的寓意?阅读文档。 Django可能是我曾经使用过的文档最好的应用程序。如果我早点完成它,那么今天我可以节省很多浪费时间,因为我可以做一些更有趣的事情。

希望这有助于某人。


2
投票

首先,ChoiceField不是一个小部件 - 它是一个Form Field

所以,改变你的形式,

class NewHouseForm(forms.ModelForm):
    CHOICES = ((1, "1"),
               (2, "2"),
               (3, "3"),
               (4, "4"),
               (5, "5"))

    rating = forms.ChoiceField(choices=CHOICES,
       widget=forms.RadioSelect(attrs={'class': 'radio-inline'}),
       )

    class Meta:
        model = NewHouse
        fields = (
            'rating',)

然后在您的自定义无线电选择template_name应该是您正在使用的模板的路径。 如果模板位于app_level“templates”子目录下或项目级“templates”子目录下,则可以执行以下操作。

class HorizontalRadioSelect(forms.RadioSelect):
    template_name = 'new_house_edit.html'

如果它位于“templates”子目录下的另一个子目录下,则需要指定模板的路径。

Django默认检查项目的每个应用程序中“templates”子目录中的模板。

© www.soinside.com 2019 - 2024. All rights reserved.