0

我本质上是想提出自己的继承方案,因为 Django 的继承不符合我的需要。

我希望父表(类)包含通用数据字段。
子类将在单独的表中拥有自己的附加数据。

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 视为 FooFooExtra的字段?

我想做类似以下的事情..

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() 将使用适当的类方法。(如果不需要,则无需加入)

  3. 何时且仅当我需要时,我才检索附加表数据(通过类似.select_related('fooextra')

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

4

2 回答 2

2

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

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


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

正如上面链接中所解释的,这将自动创建一对一的关系。当然,您可以按照上面的示例执行foo.phone = "3333"(其中footypeFoo为 )。整洁的事情是你也可以访问foo.common,而在你的例子中它本来是foo.base.common.

于 2016-05-26T08:18:58.510 回答
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实际上是 a 的对象FooProduct,您可以获取自定义字段:

product.foo.fooextra

ProductBase实际上是 a 的对象BarProduct,您可以获取自定义字段:

product.bar.barextra

您仍然可以进行查询:

foo = FooProduct.objects.get(fooextra=1)
bar = BarProduct.objects.get(barextra=2)

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

foo.common1
bar.common2 

如果您需要对查询等进行更多控制,您可以使用InheritanceManagerfrom django-model-utilsProductBase.objects.filter(...).select_subclasses() - 这也应该解决第 3 点:将为您提供FooProductandBarProduct对象而不是ProductBase对象。

于 2016-05-26T08:17:55.823 回答