在没有抽象的情况下访问父类中的基本模型字段

时间:2013-03-05 03:42:37

标签: django django-models

我正在尝试创建unicode,我想从继承表中获取字段。像这样:

 class EnvelopeBase(models.Model):
    name = models.CharField(
        max_length=50
        )
    ...........        

class Envelope(EnvelopeBase):
    category = models.ForeignKey(
        EnvelopeCategory, 
        blank=True, null=True
        )

    ........

    def __unicode__(self):
        return "{0}: {1}".format(self.category, self.name)

请注意,我正在Envelope模型中创建unicode,并且我正在尝试获取来自EnvelopeBase模型的“self.name”。我没有得到错误,但输出为空。如何访问ENvelopeBase模型中的名称字段到Envelope模型?

更新

我要做的是显示类别和信封名称,例如:

假设我有category ='Savings'和envelope ='maintenance'

输出必须是(来自unicode实现):

 def __unicode__(self):
    //the self.name here return null
    return "{0}: {1}".format(self.category, self.name)

 Output: "Savings: maintenance"

但我的问题只有 * 储蓄(类别) * 会显示无需维护(信封)。 self.name来自EnvelopeBase模型,我正试图访问Envelope模型

2 个答案:

答案 0 :(得分:2)

在django模型中使用继承时,会为父模型和子模型创建两个表。 外键列添加到子模型中,名称为Parent_ptr_id,用于引用父表中的相应行。

假设我们有两个模型(父母和孩子):

class Parent(models.Model):
    parent_field = models.CharField(max_length=50)
    def __unicode__(self):
        return self.parent_field

class Child(Parent):
    child_field = models.CharField(max_length=50)
    def __unicode__(self):
        return self.parent_field + ': ' + self.child_field

当您创建子模型的实例时,您也应该指定parent_field。

child = Child(child_field='a', parent_field='b')

如果未指定parent_field,则插入的新父行将parent_field设置为null。这可能发生在你的数据上。

此外,当您创建子模型的实例时,您可以指定现有的parent_ptr_id。

child = Child(child_field='c', parent_field='d', parent_ptr_id=1)

这会导致现有父级的parent_field更新为新值。棘手的部分是,如果您未在此处指定parent_field,则已存在的父行中的parent_field将更新为null。这也可能发生在您的数据上。

除此之外,您现有的代码应该有效。 (据我所知,不需要self.envelopebase.name)

答案 1 :(得分:1)

您希望将基本模型设为摘要https://docs.djangoproject.com/en/dev/topics/db/models/#abstract-base-classes

class EnvelopeBase(models.Model):
    name = models.CharField(
        max_length=50
    )

    ...........

    class Meta:
        abstract = True


class Envelope(EnvelopeBase):
    category = models.ForeignKey(
        EnvelopeCategory, 
        blank=True, null=True
    )

    ........

    def __unicode__(self):
        return "{0}: {1}".format(self.category, self.name)

另一种方式是多表继承https://docs.djangoproject.com/en/dev/topics/db/models/#multi-table-inheritance

基本上,您不必做任何事情。 Django自动在两者之间创建一对一的关系。基类中的所有字段都将在父类中可用,但数据将存在于不同的表中。

class EnvelopeBase(models.Model):
    name = models.CharField(
        max_length=50
    )

    ...........


class Envelope(EnvelopeBase):
    category = models.ForeignKey(
        EnvelopeCategory, 
        blank=True, null=True
    )

    ........

    def __unicode__(self):
        return "{0}: {1}".format(self.category, self.envelopebase.name)