在Django中,我有以下models.py
class Product(RandomPrimaryIdModel):
feature1 = models.CharField(max_length=20, blank=True, null=True)
feature2 = models.CharField(max_length=20, blank=True, null=True)
feature3 = models.CharField(max_length=20, blank=True, null=True)
class Mattress(Product):
category_type = models.CharField(max_length=50)
size = models.CharField(max_length=5)
def category(self):
return "bedding"
category = property(category)
我有以下views.py文件
def update(request, id):
product = Product.objects.get(id=id)
...
在此方法中,我可以从Product模型中调用“Mattress”模型中定义的方法。例如,我想写:if product.type ==“mattress”,其中类型已在Mattress模型中定义,而Mattress是Product的子模型。
答案 0 :(得分:3)
您的示例似乎介于两种不同的方式之间,但目前不正确。发生的事情是你创建了两个表:Product和Mattress,它们完全不相关。无论Mattress是Product的子类,它只是继承了它的结构。您无法在产品表中查询有关床垫的任何信息,因为床垫位于床垫表中。
一种方法是将产品视为抽象的,由实际产品进行子类化:
class Product(RandomPrimaryIdModel):
class Meta:
abstract=True
这将阻止创建Product表。然后您可以通过以下方式直接查询床垫:Mattress.objects.filter()
但这在引入多种类型的产品方面似乎有点限制,并且必须为它们管理不同的表。另一种方法是使用Product表,但使用泛型关系来支持将任何类型的其他表作为内容对象附加:
from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic
class Product(RandomPrimaryIdModel):
feature1 = models.CharField(max_length=20, blank=True, null=True)
feature2 = models.CharField(max_length=20, blank=True, null=True)
feature3 = models.CharField(max_length=20, blank=True, null=True)
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
有了这个,您就可以将content_object
设置为Mattress实例。然后,您可以使用ContentType进行查询:
p_type = ContentType.objects.get(name="mattress")
Product.objects.filter(content_type=p_type)
答案 1 :(得分:0)
这看起来像是自动向下投射的情况。对于拥有通用“ProductBase”实例的购物车,我需要类似的方法,但我需要访问子项的特定功能,这些功能是ProductDownloadable,ProductShipped等类型的实际产品。
Django本身并不支持这个,但可以通过内省或使用django-model-utils对其进行编码,一旦安装完就可以:
# return a list 'child' classes of Product - in your case Mattresses
mattress_list = Product.objects.all().select_subclasses()
# return the direct 'child' class of Product - in your case Mattress class
mattress = Product.get_subclass(id=some_id) # returns the 'child' subclass
mattress.foo() # executes method on foo on Mattress class (not on Product class)