在Django中,业务逻辑应该放在哪里?

21
例如, 帐户1--> *用户 --> 1身份验证 一个帐户有多个用户,每个用户将有1个身份验证

我来自于Java背景,所以我通常会做以下事情:

  1. 将这些类定义为Java Bean(即只有getter和setter方法,没有附加逻辑)
  2. 创建AccountManager EJB类,定义create_account方法(需要一个账户和用户列表作为参数)
  3. 在Web层中准备数据,然后将数据传递给AccountManager EJB,例如:accountManager.createAccount(account, userList)

但是在Django中,框架提倡将领域逻辑放入模型类(行级别)或相关的管理器类(表级别),这使得事情变得有点尴尬。如果您的逻辑仅涉及一个表格,则可以采用这种方式,但在实际应用中,通常每个步骤都涉及多个不同的表格,甚至是数据库,那么在这种情况下该怎么办?

把逻辑放到视图中吗?我认为这根本不是好的做法。或者通过使用**kwargs在模型类中覆盖save方法,传递额外的数据?但是后端将会出错。

我希望这说明了我在Django应用程序中应该将业务逻辑放置在何处的困惑。

3个回答

15

不确定您是否阅读了Django中关于管理器的部分,它似乎可以解决您当前的情况。假设您已经定义了以下Account模型,User是内置的。

# accounts/models.py

class AccountManager(models.Manager):
    def create_account(self, account, user_list):
        ...

class Account(models.Model):
    objects = AccountManager()

如果你的管理代码变得太大,随意将其分离到单独的文件中。在你的视图中:

# views.py

from accounts.models import Account

Account.objects.create_account(account, user_list)

业务逻辑仍然在模型中。

编辑

关键词是覆盖,而不是重写。如果您覆盖了模型的保存方法,则必须记住,来自Web应用程序和管理界面的任何创建、更新操作都将使用这个新功能。如果您只希望在特定视图中执行这些业务逻辑一次,则最好将其排除在保存之外。

我想你可以把你的业务逻辑放在一个普通类中。每次需要运行业务逻辑时,您都必须实例化该类。或者,如果您想跳过OOP方法,可以将您的业务逻辑作为这个新类中的静态函数。


1
嗨,Thierry,你觉得覆盖保存方法是个好主意吗?另外,管理器对象不应该更专注于表级逻辑吗?(只是好奇,因为现在我对你的方法非常有信心) - devharb

3

我正在做的是,我的大多数应用程序都有一个名为service.py的文件,其中包含业务逻辑。这是因为如果我需要一个函数来处理来自多个应用程序的模型,我不能简单地这样做:

# shop/models.py
from auth.models import User, Team

这段代码将会被卡在循环引用的环路中。

但是我可能会从service.py移动到具有以下结构的应用程序:

service/
    auth.py
    customers.py
    another_set_of_functions.py
    ...

0

好吧,你上面举的accountManager.createAccount(account,userList)的示例看起来很容易通过向账户模型添加一个createAccount方法来完成。如果您觉得需要将业务逻辑从模型中提取出来,您也可以创建一个新模块来承载您的业务逻辑,然后在视图中导入和使用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接