我正在为django创建两个自定义小部件,以使用所选的jQuery插件,一个用于ForeignKey
模型字段,另一个用于ManyToManyField
。因此,我分别覆盖forms.Select
和forms.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的调用,它应分别引用Select
和SelectMultiple
的渲染方法。
然后,我定义了我的课程:
class ChosenWidgetMultiple(widgets.SelectMultiple, ChosenWidgetParent):
pass
class ChosenWidget(widgets.Select, ChosenWidgetParent):
pass
不幸的是,这不起作用,但是当我交换父类时,它可以工作。
class ChosenWidgetMultiple(ChosenWidgetParent, widgets.SelectMultiple):
pass
class ChosenWidget(ChosenWidgetParent, widgets.Select):
pass
有人能解释我为什么吗?
答案 0 :(得分:1)
因为这是方法解析的工作方式。 Python将按照声明的顺序遍历类,并调用它找到的第一个方法。当你首先声明原始小部件时,Python会找到它的render方法并调用它;它永远不会继续你的实施。但是当你把它放在第一位时,Python会调用它,然后当它到达super()时会调用原来的。