将Django从1.9迁移到1.11:MultiValueField和MultiWidget行为出现问题 [英] Migrating Django from 1.9 to 1.11: trouble with MultiValueField and MultiWidget behaviour

查看:55
本文介绍了将Django从1.9迁移到1.11:MultiValueField和MultiWidget行为出现问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码可以在Django 1.9中正常工作:

Here is a code that works as expected in Django 1.9:

class MultipleBooleanField(forms.MultiValueField):
    def __init__(self, *args, **kwargs):
        self.fieldnames = kwargs.pop('fields')
        fields = [ forms.BooleanField(required=False) for x in self.fieldnames ]
        super(MultipleBooleanField, self).__init__(fields=fields,
                            require_all_fields=False, *args, **kwargs)
        self.widget = MultipleBooleanWidget(widgets=[ f.widget for f in fields ])
        self.widget.fieldnames = self.fieldnames

    def compress(self, datalist):
        # return a list of the fieldnames, datalist is a list of booleans            
        print('compress datalist:', datalist)
        if self.required and not any(datalist):
            raise forms.ValidationError('You must choose at least one value')
        return [ self.fieldnames[i] for i in range(len(datalist)) if datalist[i] ]

class MultipleBooleanWidget(forms.MultiWidget):
    def render(self, name, value, attrs=None, renderer=None):
        if not value:
            value = [ False for x in self.fieldnames ]
        rendered_widgets = [ x.render(name, value[i]) for i,x in enumerate(self.widgets) ]
        items = [ '%s %s' % (rendered_widgets[i], f)
                                for (i,f) in enumerate(self.fieldnames) ]
        return ' '.join(items)

    def decompress(self, value):
        # return a list of booleans, value is a list of fieldnames
        print('decompress value:', value)
        if not value:
            return [ False for x in self.fieldnames ]
        return [ x in value for x in self.fieldnames ]

在Django 1.11中,它不再起作用,总是会引发 ValidationError 数据列表始终是仅包含 False 的列表。 从未调用过解压缩方法

With Django 1.11, it no more works, the ValidationError is always raised. The datalist is always a list containing only False. The decompress method is never called.

我试图实现 value_from_datadict 方法非常老的帖子中建议,但没有成功。

I tried to implement a value_from_datadict method as suggested in very old posts, but no success.

我看一下Djando代码,似乎是Django不喜欢将字段的结果( compress 的返回值)作为列表,所以我尝试将其转换为字符串(以逗号连接的值)。

I take a look to Djando code and it seems that Django does not like the result of the field (the return value of compress) to be a list, so I tried to transform it into a string (as comma joined values). But the behaviour remains the same.

有什么想法吗?

编辑:
查看HTML源代码,看来子控件未正确呈现:它们都具有相同的名称,并且没有id。假设字段名称为 Valeurs

在Django 1.9中,HTML为:

In Django 1.9, the HTML is:

<tr><th><label for="id_Valeurs_0">Valeurs :</label></th><td><input checked="checked" id="id_Valeurs_0" name="Valeurs_0" type="checkbox" /> Part du total com <input checked="checked" id="id_Valeurs_1" name="Valeurs_1" type="checkbox" /> Part du total Qté <input checked="checked" id="id_Valeurs_2" name="Valeurs_2" type="checkbox" /> ...

在Django 1.11中,HTML为:

In Django 1.11, the HTML is:

<tr><th><label for="id_Valeurs_0">Valeurs :</label></th><td><input type="checkbox" name="Valeurs" checked /> Part du total com <input type="checkbox" name="Valeurs" checked /> Part du total Qté <input type="checkbox" name="Valeurs" checked /> 

我还有其他的 MultiValueField / MultiWidget 正确,写得非常相似。我真的不明白问题出在哪里。

I have others MultiValueField/MultiWidget that work correctly, written very similarly. I really don't understand where is the problem.

推荐答案

此处是发行说明所说的


删除了Widget.format_output()方法。改用自定义窗口小部件模板。

The Widget.format_output() method is removed. Use a custom widget template instead.

https://docs.djangoproject.com/zh-CN/1.11/releases/1.11/#由于基于模板的小部件渲染的引入而发生的变化

这篇关于将Django从1.9迁移到1.11:MultiValueField和MultiWidget行为出现问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆