Python Django,把OneToOne相关的领域当作我自己的领域
我基本上是想提出我自己的继承方案,因为Django的继承不符合我的需要 我希望父表(类)包含公共数据字段。Python Django,把OneToOne相关的领域当作我自己的领域,python,django,django-inheritance,Python,Django,Django Inheritance,我基本上是想提出我自己的继承方案,因为Django的继承不符合我的需要 我希望父表(类)包含公共数据字段。 子类将在一个单独的表中有自己的附加数据 class ProductBase(models.Model): common = models.IntegerField() def get_price(self): return some_price class FooProduct(ProductBase): # no field becaus
子类将在一个单独的表中有自己的附加数据
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视为具有footera
的字段
我想做如下事情
foo = FooProduct.objects.create()
foo.phone = "3333" # as django does with its multiple inheritance
foo.save()
FooProduct.objects.filter(phone="3333")
我想列出不同种类的产品(数据)
的方式。选择\u related('footextra')
很接近我想要的,但它的功能相当模糊,所以我害怕使用它,我认为它失败了#3。看起来你并不想要任何不同于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
从实际上是FooProduct
的ProductBase
对象中,您可以通过以下方式获得自定义字段:
product.foo.fooextra
product.bar.barextra
从实际上是BarProduct
的ProductBase
对象中,您可以通过以下方式获得自定义字段:
product.foo.fooextra
product.bar.barextra
您仍然可以执行以下操作:
foo = FooProduct.objects.get(fooextra=1)
bar = BarProduct.objects.get(barextra=2)
您可以直接访问这些对象上的公共字段:
foo.common1
bar.common2
如果需要对查询等进行更多控制,可以使用中的
InheritanceManager
,这也应该解决第3点:ProductBase.objects.filter(…)。选择子类()
将为您提供foodproduct
和BarProduct
对象,而不是ProductBase
对象。您似乎并不希望与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
从实际上是FooProduct
的ProductBase
对象中,您可以通过以下方式获得自定义字段:
product.foo.fooextra
product.bar.barextra
从实际上是BarProduct
的ProductBase
对象中,您可以通过以下方式获得自定义字段:
product.foo.fooextra
product.bar.barextra
您仍然可以执行以下操作:
foo = FooProduct.objects.get(fooextra=1)
bar = BarProduct.objects.get(barextra=2)
您可以直接访问这些对象上的公共字段:
foo.common1
bar.common2
如果需要对查询等进行更多控制,可以使用中的
InheritanceManager
,这也应该解决第3点:ProductBase.objects.filter(…)。选择子类()
将为您提供foodproduct
和BarProduct
对象,而不是ProductBase
对象。如果我理解清楚,您希望继承,并且希望子类特定的字段位于单独的表中。
据我所知,您不需要代理类来实现这一点,您可以按照手册中的规定实现多表继承,例如:
如上链接所述,这将自动创建一对一关系。当然,您可以执行
foo.phone=“3333”
(其中foo
类型为foo
)就像上面的例子一样。最妙的是,你也可以访问foo.common
,而在你的例子中,如果我理解得很好,你应该是foo.base.common
,你想要继承,你想要子类特有的字段在一个单独的表上。
据我所知,您不需要代理类来实现这一点,您可以按照手册中的规定实现多表继承,例如:
如上链接所述,这将自动创建一对一关系。当然,您可以执行
foo.phone=“3333”
(其中foo
类型为foo
)就像你上面的例子一样。最妙的是,你也可以访问foo.common
,而在你的例子中,它应该是foo.base.common
,Django的默认模型继承对你不起作用的原因是什么?@Ben:我编辑了这个问题来解决这个问题。Django的默认模型继承是什么这对你不起作用吗?@Ben:我编辑了这个问题来解决这个问题。回答很好,你比我快了1分钟:-)我认为它失败了#2,polymorphic
,如果base有def price(self)
,而foo有自己的版本ProductBase.objects.all():
不会使用多态价格。如果从模型utils调用select_子类,则会使用多态价格package@ben:这会导致连接并违反#3,我不想为多态行为连接(除非我需要)您确定它在需要时不会这样做,而不是最初这样做吗?我还没有测试,所以我不知道。另外,除非你已经测试过,而且性能对你来说太慢了,否则我不确定这个要求背后的原因是什么。回答不错,你比我快了1分钟:-)我认为它失败了#2,polymorphic
,如果base有def price(self)
,而foo有自己的版本ProductBase.objects.all():
不会使用多态价格。如果从模型utils调用select_子类,则会使用多态价格package@ben:这会导致连接并违反#3,我不想为多态行为连接(除非我需要)您确定它在需要时不会这样做,而不是最初这样做吗?我还没有测试,所以我不知道。另外,除非您已经测试过,而且性能对您来说太慢,否则我不确定该要求背后的原因是什么。