Shi*_*dla 3 python forms django super models
实际上我们知道super用于查找"父类"并返回其对象,例如/ usingself.__class__.__mro__
我很困惑的是什么时候使用它?
假设我们有一个示例模型代码,如下所示
VERSION_1
class Example(models.Model):
name = models.CharField()
age = models.IntegerField()
def save(self, **args, **kwargs):
obj = super(Example, self).save(self, **args, **kwargs)
obj.name = "name changed"
obj.age = "age changed"
return obj
Run Code Online (Sandbox Code Playgroud)
VERSION_2
class Example(models.Model):
name = models.CharField()
age = models.IntegerField()
def save(self, **args, **kwargs):
self.name = "name changed"
self.age = "age changed"
obj = super(Example, self).save(self, **args, **kwargs)
return obj
Run Code Online (Sandbox Code Playgroud)
所以我们可以在上面观察
在version_1中,我先调用super并对字段进行了修改并返回了obj
在版本_2中,我修改了字段,之后调用了super并返回了obj
那么在修改字段之前和之后调用super时会发生什么?
最后我想知道/确认的是
Jan*_*nis 13
你的Example类是它的子类Model.这意味着,它Example继承了所有函数Model.
请看以下内容:
class Example():
pass
example = Example()
#let's try to save it
example.save()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: Example instance has no attribute 'save'
Run Code Online (Sandbox Code Playgroud)
现在继承.
class Parent():
def save(*args, **kwargs):
print "saving now"
class Example(Parent):
pass
example = Example()
#since Example has no save method, it inherits the Parent's save method.
example.save()
"saving now"
Run Code Online (Sandbox Code Playgroud)
如果覆盖Example类中的save()方法,则不会调用Parent的save方法.
class Example(Parent):
def save(self, *args, **kwargs):
print "i know how to save on my own now"
example = Example()
example.save()
"i know how to save on my own now"
Run Code Online (Sandbox Code Playgroud)
如果您选择调用super,则调用Parent的save函数以及您自己的save()实现.
class Example(Parent):
def save(self, *args, **kwargs):
super(Example, self).save(*args, **kwargs)
print "i know how to save on my own now"
example = Example()
example.save()
"saving now" #from parent
"i know how to save on my own" #from example
Run Code Online (Sandbox Code Playgroud)
这同样适用于您继承的所有djangos类.实际上,实施更复杂.您可以在github上查看模型定义.
如果您感到激动,可以通过本次演讲深入了解django ORM
我相信这个问题不是特定于 Django 的,因此我将尝试以通用的方式解释它。
super 的实用性在于您不需要指定要调用哪个基类(这也可能是一个缺点,因为 mro 定义了调用什么基类)。
我使用 super 创建 mixin(SO 上有一个很好的答案,描述了 mixin 是什么)。一个使用 super 的例子:
class LemonMixin(object):
def tastes_like(self):
return super(LemonMixin, self).tastes_like() + ' and lemon'
class Cola(object):
def tastes_like(self):
return 'sugar'
class ColaLemon(LemonMixin, Cola):
pass
drink = ColaLemon()
drink.tastes_like() # returns 'sugar and lemon'
Run Code Online (Sandbox Code Playgroud)
mixin 与 aplied 类无关,因此它可以使用 super 来使用 mro 来调用基类。
何时调用 super 完全取决于您。例如,如果您想检查安全性,请在安全性检查后调用 super。如果您想在某事完成时触发事件,您可能需要在触发事件之前调用 super。;-)