Django,将OneToOne相关字段视为我自己的字段

时间:2016-05-26 07:51:24

标签: python django django-inheritance

我基本上试图提出自己的继承方案,因为Django的继承不符合我的需要。

我希望父表(类)保存公共数据字段 sub classess将在一个单独的表中拥有自己的附加数据。

class ProductBase(models.Model):

    common = models.IntegerField()

    def get_price(self):
        return some_price


class FooProduct(ProductBase):

    # no field because I'm proxy

    class Meta:
        proxy = True

    def get_price(self):
        return price_using_different_logic


class FooExtra(models.Model):

    base = models.OneToOneField(ProductBase, primary_key=True)
    phone = models.CharField(max_length=10)

我的问题是,是否可以将Foo视为FooExtra的字段?

我想做以下事情..

foo = FooProduct.objects.create()

foo.phone = "3333"  # as django does with its multiple inheritance
foo.save()
FooProduct.objects.filter(phone="3333")  

我想列出不同种类的产品(数据)

  1. 我需要将它们列在一起,所以抽象的Base继承已经不在了

  2. 从列表中,我想将每个模型视为多态模型,当迭代ProductBase.objects.all()时,product.get_price()将使用适当的classe方法。 (如果没有,则不招致加入)

  3. 当且仅当我需要时,我会检索地址表数据(通过类似.select_related('fooextra')

  4. 的方式

    Django-polymorphic接近我想要的东西,但它的含义相当模糊,所以我害怕使用它,我认为它失败了#3。

2 个答案:

答案 0 :(得分:2)

如果我理解得很好,您需要继承,并且您希望子类特定的字段位于单独的表中。 据我所知,您不需要代理类来实现这一点,您可以按照https://docs.djangoproject.com/en/1.9/topics/db/models/#multi-table-inheritance手册中指定的方式实现多表继承,例如:

class Base(models.Model):
    common = models.IntegerField()


class Foo(Base):
    phone = models.CharField(max_length=10)

如上面的链接所述,这将自动创建一对一的关系。当然,您可以执行foo.phone = "3333"(其中foo类型为Foo),如上例所示。而且整洁的是,您也可以访问foo.common,而在您的示例中,它应该是foo.base.common

答案 1 :(得分:1)

看起来你不想要任何与Django标准继承不同的东西。

class ProductBase(models.Model):
    common1 = models.IntegerField()
    common2 = models.IntegerField()

class FooProduct(ProductBase):
    fooextra = models.IntegerField()

class BarProduct(ProductBase):
    barextra = models.IntegerField()

如果您创建每个实例:

foo1 = FooProduct(common1=1, common2=1, fooextra=1)
foo2 = FooProduct(common1=1, common2=1, fooextra=2)
bar1 = BarProduct(common1=1, common2=1, barextra=1)
bar2 = BarProduct(common1=1, common2=1, barextra=2)

您可以遍历所有产品:

for product in ProductBase.objects.all():
    print product.common1, product.common2

从实际为ProductBase的{​​{1}}对象中,您可以获取自定义字段:

FooProduct

从实际为product.foo.fooextra 的{​​{1}}对象中,您可以获取自定义字段:

ProductBase

您仍然可以进行查询:

BarProduct

您可以直接在这些对象上访问公共字段:

product.bar.barextra

如果您需要对查询等有更多控制权,可以使用django-model-utils中的foo = FooProduct.objects.get(fooextra=1) bar = BarProduct.objects.get(barextra=2) - 这也应该针对第3点:foo.common1 bar.common2 会为您提供InheritanceManagerProductBase.objects.filter(...).select_subclasses()个对象,而不是FooProduct个对象。