你不需要阅读所有这篇文章来帮助我回答这个问题,这篇文章的其余部分只是提出问题的背景,但一般的问题是:
在Django中放置跨越多个模型的业务逻辑?
一些可能性:
上下文
我有这个型号:
假设我在Django管理员中并且我去了部门风险,而风险目前已经分配了Project1和Project2。当我添加一名新员工“Jhon Smith”(例如,使用部门中的内联表单)并按下保存按钮时,我希望模型历史记录更新时会显示以下信息:
Membership table (only important fields): pk Department Employee join_date leave_date 20 Risk Jhon Smith xxxx xxxx History Table (only important fields): Membership Project 20 Project1 20 project2
我的意思是,当新员工被分配到新部门时,必须将该部门的所有实际项目分配到表历史记录中的该成员资格员工部门。
问题是将这个逻辑放在Django中的哪个位置?你可以看到这个逻辑涉及多个模型,一些可能性是:
注意事项:如果代码可以在流程中的任何一点生成一个valueerror并且用户/管理员能够以无界形式看到此错误,那将是很好的。
答案 0 :(得分:3)
我只是评论逻辑应该存在的方面。这对我来说听起来像模型逻辑。 Django有一个略微复杂的MVC概念。当它纯粹的数据关系时,我相信它的所有模型逻辑。我建议尽可能将方法放在尽可能接近模型的位置,并简单地从触发模型中调用最小的调用。
如果你非常关心解耦应用程序,那么你可以使用信号。而不是模型A知道它需要在保存期间调用XYZ,而是另一种方式。模型A只发出一个信号。 XYZ将负责连接信号。您甚至可以在完全通用的项目应用程序中进行信号定义,在这种情况下,触发模型或接收模型都不了解每个操作。它只会束缚他们。
有一些内置信号,例如模型之前和after a save,这意味着如果您正在寻找保存触发器,则不必发出自定义内容。但是,让我们说在一个模型逻辑的各个点上你需要发出一个自定义信号,如“名称已更改”,你可以发出自己的信号。
模型A
import django.dispatch
name_changed = django.dispatch.Signal(providing_args=["name"])
class ModelA:
...
def foo:
# something happened here
name_changed.send(sender=self, name=the_name)
模型B,C,D
from myApp.modelA import name_changed
name_changed.connect(modelB.handle_name_change, dispatch_uid="my_unique_identifier")
name_changed.connect(modelC.handle_name_change, dispatch_uid="my_unique_identifier")
name_changed.connect(modelD.handle_name_change, dispatch_uid="my_unique_identifier")
我个人习惯为需要一些通用“控制器模型”逻辑的应用程序创建一个utils.py模块。他们更像是行动或帮助者。
答案 1 :(得分:0)
也许问题是你在那里的“历史”表。我不知道你在Project
表中有什么样的信息。但是,如果每个项目都有一个开始和结束日期,那么您的历史记录表将处理重复信息。在这种情况下,如果您想知道哪个项目对员工起作用,您只需要知道该员工在该部门工作的日期范围,然后您需要找到该部门之间开发的项目。以前的日期范围。
我希望你理解我的观点。如果没有,请告诉我,以便我能更好地解释它(可能有一个例子)。
但是,当我理解你的问题和你的模型时,我认为你不需要那个历史表。它将重复信息......
因此,如果您的Project
模型具有此信息(日期范围),则解决方案应该存在于经理中,因为只需找到您希望存在于多个表中的信息... < / p>
希望它有所帮助!