django - 应用程序和模型继承的松散耦合

标签 django django-models

我有一个关于 Django 的设计问题。我不太确定如何将应用程序松散耦合的原则应用于这个特定问题:

我有一个管理订单的订单应用程序(在网上商店)。在这个订单应用程序中,我有两个类:

class Order(models.Model):
    # some fields
    def order_payment_complete(self):
        # do something when payment complete, ie. ship products
        pass

class Payment(models.Model):
    order = models.ForeignKey(Order)
    # some more fields     
    def save(self):
        # determine if payment has been updated to status 'PAID'
        if is_paid:
            self.order.order_payment_complete()
        super(Payment, self).save()

现在的实际问题是:我有一个更专业的应用程序可以扩展此订单。因此它添加了更多字段等。示例:

class SpecializedOrder(Order):
    # some more fields
    def order_payment_complete(self):
        # here we do some specific stuff
        pass

现在,预期的行为当然如下:我创建一个 SpecializedOrder,对该订单进行付款,并调用 SpecializedOrder 的 order_ payment_complete() 方法。但是,由于 Payment 链接到 Order,而不是 SpecializedOrder,因此将调用基本 Order 的 order_ payment_complete() 方法。

我真的不知道实现这种设计的最佳方法。也许我完全不在意 - 但我想构建这个订单应用程序,以便我可以将它用于多种目的,并希望使其尽可能通用。

如果有人能帮助我,那就太好了! 谢谢, 尼诺

最佳答案

我认为您正在寻找的是 GenericForeignKey来自 ContentTypes 框架,该框架在 contrib 包中随 Django 一起提供。它负责记录子类实例的类型和 ID,并提供一种无缝方式来访问子类作为模型上的外键属性。

就您而言,它看起来像这样:

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

class Payment(models.Model):

    order_content_type = models.ForeignKey(ContentType)
    order_object_id = models.PositiveIntegerField()
    order = generic.GenericForeignKey('order_content_type', 'order_object_id')

您无需执行任何特殊操作即可使用此外键...泛型透明地处理设置并保存 order_content_typeorder_object_id 字段:

s = SpecializedOrder()
p = Payment()
p.order = s
p.save()

现在,当您的 Payment 保存方法运行时:

if is_paid:
    self.order.order_payment_complete()  # self.order will be SpecializedOrder

关于django - 应用程序和模型继承的松散耦合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1259580/

相关文章:

Django 1.4 预取相关不保留继承模型的结果

python - Django 使用 PyCharm 时出错 : "' function' object has no attribute 'using' "

django - 如何排除 Django 循环中的项目?

Django rest 框架 DateField 格式

django - 从Django Rest框架中的序列化器发送自定义错误响应?

django - 在 Django Rest Framework 中跨应用程序将自定义路由器扩展到默认路由器

python - Django 使用相关查询集的第一个元素进行注释

Django Postgres DateRangeField - 我可以使用唯一的验证器吗

python - 在 python 中,我如何检查一个对象是否有值?

django - 错误: Cannot find module 'socket.io/node_modules/redis'