在Django中创建智能类工厂

1 投票
3 回答
3068 浏览
提问于 2025-04-16 13:14

我已经尝试了很久想搞明白这个问题,但收效甚微。我想写一个类工厂,让它能和Django的ORM(对象关系映射)很好地配合,这样我就可以用像这样的模型结构:

Product
    SubclassOfProduct0
    SubclassOfProduct1
    ....

来实现像这样的功能:

Product.objects.get(pk=7) // returns the result of SubclassOfProduct0(pk=7)
Product.objects.filter(propname="w00t") // returns a QuerySet of Product objects

所以我在想可以这样做:

class ProductManager(models.Manager):
    def get(self, *a, **kwa):
        # Get the id from Products (somehow)
        if product.type == Product.TYPE_SUBCLASS0:
            return ProductSubClass0.objects.get(pk=kwa["pk"])


class Product(models.Model):

    TYPE_SUBCLASS0 = 0
    TYPE_SUBCLASS1 = 1

    objects = ProductManager()

    def __init__(self, *a, **kwa):
        self.set_defaults()

    def set_defaults(self):
        pass


class ProductSubClass0(models.Model):
    def set_defaults(self):
        self.type == self.TYPE_SUBCLASS0

...但我不知道怎么做才算是“正确”的做法。有没有人能给我一些建议?

3 个回答

0

你可以使用实体框架和通用关系。比如,在models.py文件中:

from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic

# Product
class Product(models.Model):
    name = models.CharField(max_length=128)
    pub_date = models.DateTimeField('date published', null=True)
    productDescription = models.CharField(max_length=400)

    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('content_type', 'object_id')


#Shirt Product type
class ShirtProduct(models.Model):
    product  = generic.GenericRelation(Product)



#Book Product type
class BookProduct(models.Model):
    product  = generic.GenericRelation(Product)

....

如果你想查找一个产品的ID,可以在你的ProductManager里使用这个方法: product = generic.GenericRelation(Product, content_type_field='content_type_fk', object_id_field='object_primary_key')

(关于反向通用关系的更多信息,可以参考这个Django项目页面

0

你可以通过创建一个新的类来继承你的 Product 类,具体的做法可以参考这里的说明:http://docs.djangoproject.com/en/1.2/topics/db/models/#model-inheritance

class OtherProduct(Product):
    battery_life = …

如果你不打算直接使用 Product,也可以把它设置成一个抽象基类。

2

Django Tagging 在它的 models.py 文件中提供了一个很好的例子,展示了它是如何识别特定类的内容类型的。我现在在我开发的另一个模块中也使用了这个方法,里面涉及到权限管理。

撰写回答