python

时间:2016-11-14 13:57:57

标签: python django

我正在为django创建两个自定义小部件,以使用所选的jQuery插件,一个用于ForeignKey模型字段,另一个用于ManyToManyField。因此,我分别覆盖forms.Selectforms.SelectMultiple。我将常用功能放在一个公共父类中:

class ChosenWidgetParent(object):
    class Media:
        css = {
            'all': (
                'sub/staticfull/css/plugins/chosen/chosen.css',
            )
        }
        js = (
            'sub/staticfull/js/jquery-2.1.1.js',
            'sub/staticfull/js/plugins/chosen/chosen.jquery.js',
        )
    def render(self, name, value, attrs=None, **kwargs):
        attrs['chosen'] = 'chosen'
        rendered = super().render(name, value, attrs, **kwargs)
        return rendered + mark_safe(u'''
            <script>
                $(document).ready(function () {
                   $('#id_%(name)s').chosen({
                        disable_search_threshold: 10,
                   })
                })
            </script>''' % {'name': name})

注意有一个对super的调用,它应分别引用SelectSelectMultiple的渲染方法。

然后,我定义了我的课程:

class ChosenWidgetMultiple(widgets.SelectMultiple, ChosenWidgetParent):
    pass

class ChosenWidget(widgets.Select, ChosenWidgetParent):
    pass

不幸的是,这不起作用,但是当我交换父类时,它可以工作。

class ChosenWidgetMultiple(ChosenWidgetParent, widgets.SelectMultiple):
    pass

class ChosenWidget(ChosenWidgetParent, widgets.Select):
    pass

有人能解释我为什么吗?

1 个答案:

答案 0 :(得分:1)

因为这是方法解析的工作方式。 Python将按照声明的顺序遍历类,并调用它找到的第一个方法。当你首先声明原始小部件时,Python会找到它的render方法并调用它;它永远不会继续你的实施。但是当你把它放在第一位时,Python会调用它,然后当它到达super()时会调用原来的。