构建Django应用以将自定义业务规则附加到对象实例

0 投票
1 回答
783 浏览
提问于 2025-04-16 07:28

我在想怎么组织我的代码,以便能处理特定模型实例的业务规则。

举个例子,假设我有一个联系人模型,这个模型里有一个类型字段,choices=(('I','个人'),('C','公司'))。根据我拥有的模型类型,我可能想要一些自定义的方法。

所以我在想,像这样做会很好:

class IndividualContact(Contact):
""" A custom class used for Contact instances with type='I' """
    criteria = Q(type='I')

# The goal here is that Contact is now aware of IndividualContact and constructs
# objects accordingly.
Contact.register(IndividualContact)

甚至可以这样:

class SpecialContact(Contact):
""" A custom class used for the contact with pk=1 """
    criteria = Q(pk=1)

这样我就有了一个很好的地方来放我的特定实例代码。

我考虑的一个替代方案是使用模型继承,避免使用像类型字段这样的东西,因为它们会引入新的行为。这样,新类可以优雅地融入现有框架,如果需要的话,你也可以轻松地为不同类型添加自定义字段。

在我的情况下,我的网站上有一个资源信用系统,可以让我说“你最多只能有2个列表和20张照片”。不同的资源类型是有配额的,但有一个通用的信用表,可以为各种内容类型提供信用。计算你的列表和照片的逻辑会根据你正在处理的对象类型而有所不同。

也就是说:

listing_credit = Credit.objects.create(content_type=ContentType.objects.get_for_model(Listing), user=user, credit_amt=2)

# Should subtract **active** listings from current sum total of Listing credits.
listing_credit.credits_remaining()

photo_credit = Credit.objects.create(content_type=ContentType.objects.get_for_model(Photo), user=user, credit_amt=5)

# Photos have no concept of an active status, so we just subtract all photos from the current sum total of Listing credits. 
# Also, the Photo might be associated to it's user through a 'created_by' field whereas
# Listing has a user field.  
photo_credit.credits_remaining()

我现在的做法是使用不同的类,但我想减少这种重复代码的情况,以及创建多个只有credit_ptr_id的表的必要性。

1 个回答

1

看看Django的代理模型吧。它们可以让你实现你想要的功能。

http://docs.djangoproject.com/en/dev/topics/db/models/#proxy-models

不过因为在你的情况下,行为是依赖于字段的值的,所以你应该给代理模型添加自定义管理器,这样在查询时只会获取特定类型的项目。

撰写回答