Django 模型继承-如何使用重写的方法?
我有以下代码:Django 模型继承-如何使用重写的方法?,django,django-models,Django,Django Models,我有以下代码: # apps/models.py : class Parent(models.Model): name = models.CharField(max_length=80) def __unicode__(self): clist = ", ".join([x.__unicode__() for x in self.children.all()]) return self.name + clist class Child(
# apps/models.py :
class Parent(models.Model):
name = models.CharField(max_length=80)
def __unicode__(self):
clist = ", ".join([x.__unicode__() for x in self.children.all()])
return self.name + clist
class Child(models.Model):
unit = models.ForeignKey(Parent, related_name='children')
desc = models.CharField(max_length=80)
def __unicode__(self):
return self.desc
class ChildA(Child):
text = models.TextField()
def __unicode__(self):
return self.text[:40]
我有几件ChildA
类型的物品。为什么当我要求相关的父级的\uuuuunicode\uuuuuuu()
时,我得到的返回字符串是由子级的方法生成的字符串,而不是子级的\uunicode\uuuuuuu()
方法生成的字符串
更新:
这是标准行为。除了下面的答案之外,另一个可能的解决方案是一个您可能需要一个抽象基类
请仔细阅读此处的差异。。。
为什么当我要求相关父级的unicode()时,字符串I
get-in-return是由
孩子
因此,您没有在父实例上调用该方法。这就是您看到这种行为的原因。您可以使用super()
关键字访问父类的方法:
a = ChildA()
#This will give you the normal method:
print unicode(a)
#super() will give you the parent's method:
super(ChildA, a).__unicode__()
您不能简单地将unicode()
函数用于后一个调用,因为super
将代理返回给对象,而不是对象本身
这不是编写代码的好方法。让类根据自己的意愿重写行为。这是继承的标准行为<代码>父项
与子项
直接相关,而不是子项
。当你调用some\u parent.children.all()
时,你会得到一个Child
实例的查询集,所以很明显,当你调用其中一个unicode
时,它调用的是Child.\uuu unicode\uuncode
更新
从父母那里得到孩子并不是一个好办法。如果您使用的是MTI(多表继承),那么可以利用Django实现它的方式,即作为父级的OneToOneField
。因此,父对象与子对象之间也存在反向关系,但您必须对其进行专门测试。例如:
class Child(models.Model):
...
def get_child(self):
if hasattr(self, 'childa'):
return self.childa
if hasattr(self, 'childb'):
return self.childb
...
无论如何,它都不是理想的方法,当你为Child
子类时,你需要小心地总是更新这个方法,这几乎完全违反了OOP中的抽象。我不能使用抽象类,因为我需要相关的\u名称
功能,并且我需要使用一个单独的名称(children
,在我的示例中)。我在父对象上调用该方法。父对象。
方法在中循环
所有子级的方法,但它是原始方法,而不是重写版本。系统似乎像父模型一样引用继承模型@Marcin@Ohad请将输出和代码放入您的问题中,并进行适当的编辑。在任何情况下,我看不出这表明您正在收到s的结果ub实例unicode方法。我不确定复制我所描述的情况是否有必要,但我会尽量使其更简洁,稍后再编辑,因为可能我遗漏了一些东西。谢谢。撒谎和忽略一些可能是解决问题的关键的东西是有区别的,这可能就是你想要的我正在做。谢谢你的帮助。请拿出一些证据表明你正在做你认为正在做的事情。如果你刚刚开始和Django一起开发,我建议你不要使用。考虑使用更简单、更容易出错的方法。你会很满意。酷。至少我知道这不是我错过的。P是什么?此行为的可行变通方法,以便我可以访问某些\u parent.children.all()
?很好!您还可以在get\u child()方法底部添加一个“assert False”语句,以在运行时获取列表中缺少某个派生类的证据