我基本上试图提出自己的继承方案,因为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")
我想列出不同种类的产品(数据)
我需要将它们列在一起,所以抽象的Base继承已经不在了
从列表中,我想将每个模型视为多态模型,当迭代ProductBase.objects.all()时,product.get_price()将使用适当的classe方法。 (如果没有,则不招致加入)
当且仅当我需要时,我会检索地址表数据(通过类似.select_related('fooextra')
Django-polymorphic接近我想要的东西,但它的含义相当模糊,所以我害怕使用它,我认为它失败了#3。
答案 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
会为您提供InheritanceManager
和ProductBase.objects.filter(...).select_subclasses()
个对象,而不是FooProduct
个对象。