如何在 Django 中访问"sub-model"方法?



在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.type == "床垫",其中类型已在床垫模型中定义,并且床垫是产品的子模型。

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

一种方法是将产品视为抽象的,由实际产品进行子类化:

class Product(RandomPrimaryIdModel):
    class Meta:
        abstract=True

这将阻止创建产品表。然后,您将通过以下方式直接查询床垫: 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设置为床垫实例。然后,您可以使用内容类型进行查询:

p_type = ContentType.objects.get(name="mattress")
Product.objects.filter(content_type=p_type)

这看起来像是自动向下铸造的情况。对于包含通用"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)

最新更新