-1

在 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 模型中调用“床垫”模型中定义的方法吗?例如,我想写: if product.type == "mattress" 其中类型已在床垫模型中定义,并且床垫是 Product 的子模型。

4

2 回答 2

3

您的示例似乎介于两种不同的方式之间,但目前不正确。发生的情况是您正在创建两个表:Product 和 Mattress,它们完全不相关。不管 Mattress 是 Product 的子类,它只是继承了它的结构。您无法查询 Product 表中有关床垫的任何内容,因为床垫位于 Mattress 表中。

一种方法是考虑一个产品只是抽象的,被实际产品子类化:

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)
于 2012-08-10T00:35:27.950 回答
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)
于 2012-08-10T04:22:45.083 回答