在django中放置业务逻辑的位置

时间:2021-11-07 18:05:59

For example, Account 1--> *User --> 1 Authentication 1 account has multiple users and each user will have 1 authentication

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

I come from java background so what I usually do is

我来自java背景,所以我通常做的是

  1. define these classes as java beans (ie, just getter and setter, no logic attached)
  2. 将这些类定义为java bean(即,只是getter和setter,没有附加逻辑)
  3. create AccountManager ejb class, define create_account method (with takes 1 account, list of users)
  4. 创建AccountManager ejb类,定义create_account方法(带1个帐号,用户列表)
  5. preparing data in the web layer, then pass data into AccountManager ejb, for instance: accountManager.createAccount(account, userList)
  6. 准备Web层中的数据,然后将数据传递到AccountManager ejb,例如:accountManager.createAccount(account,userList)

But in django, the framework advocates that you put domain logic into model classes (row level) or associated manager classes (table level), which makes things bit awkward. Yes, it is fine that if your logic is only involves one table, but in the real application, usually each step will involve multiple different tables or even databases, so what should I do in this case?

但是在django中,框架主张将域逻辑放入模型类(行级)或关联的管理器类(表级),这使得事情有点尴尬。是的,如果您的逻辑只涉及一个表,但在实际应用程序中,通常每个步骤都涉及多个不同的表甚至数据库,那很好,所以在这种情况下我应该怎么做?

Put the logic into View? I don't think this is good practice at all. or even overwrite the save method in model class, passing in extra data by using **kwargs? then the backend will break.

将逻辑放入View中?我认为这根本不是好的做法。甚至覆盖模型类中的save方法,使用** kwargs传入额外的数据?然后后端会破裂。

I hope this illustrates my confusion with where business logic should be placed in a django application.

我希望这说明我对业务逻辑放在django应用程序中的位置感到困惑。

3 个解决方案

#1


12  

Not sure if you've read the section on Managers in Django, it seems to solve your current situation. Assuming you have the following Account model defined, User is built-in.

不确定你是否已阅读Django中关于Managers的部分,它似乎解决了你目前的情况。假设您定义了以下帐户模型,则用户是内置的。

# accounts/models.py

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

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

Feel free to separate your manager code in a separate file if it gets too big. In your views:

如果管理器代码太大,请随意将其分隔在单独的文件中。在您的观点中:

# views.py

from accounts.models import Account

Account.objects.create_account(account, user_list)

The business logic is still in the models.

业务逻辑仍然在模型中。

EDIT

编辑

The keyword here is override, not overwrite. If you override the model's save method, you have to keep in mind that any create, update operations from within your web app and admin will use this new functionality. If you only want those business logic to happen once in a specific view, it might be best to keep it out of save.

这里的关键字是覆盖,而不是覆盖。如果您覆盖模型的保存方法,则必须记住,您的Web应用程序和管理员中的任何创建,更新操作都将使用此新功能。如果您只希望这些业务逻辑在特定视图中发生一次,则最好不要将其保存。

I guess you can put your business logic in its own regular class. You will have to instantiate that class each time you need to run your business logic. Alternatively, you can put your business logic as a static function in this new class if you want to skip the OOP approach.

我想你可以将你的业务逻辑放在自己的常规类中。每次需要运行业务逻辑时,都必须实例化该类。或者,如果要跳过OOP方法,可以将业务逻辑作为静态函数放在此新类中。

#2


2  

What I'm doing is that most of my apps have service.py file with business logic. This is because if I need a function that works with models from multiple apps I simply cannot do this:

我正在做的是我的大多数应用程序都有带有业务逻辑的service.py文件。这是因为如果我需要一个适用于多个应用程序模型的函数,我根本无法做到这一点:

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

This code will be stuck in circular reference loop.

此代码将卡在循环引用循环中。

But I'm gonna move most likely from service.py to app with structure like this:

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

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

#3


0  

Well the example that you illustrated above with the accountManager.createAccount(account, userList) seems like something that could be easily done my adding a createAccount method to the account model. If you feel the need to take business logic outside of the model though you could always just create a new module that host your business logic, and then import and used in in your views.

以上使用accountManager.createAccount(account,userList)说明的示例似乎可以通过向帐户模型添加createAccount方法轻松完成。如果您觉得需要在模型之外采用业务逻辑,尽管您可以随时创建一个托管业务逻辑的新模块,然后在视图中导入和使用。

#1


12  

Not sure if you've read the section on Managers in Django, it seems to solve your current situation. Assuming you have the following Account model defined, User is built-in.

不确定你是否已阅读Django中关于Managers的部分,它似乎解决了你目前的情况。假设您定义了以下帐户模型,则用户是内置的。

# accounts/models.py

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

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

Feel free to separate your manager code in a separate file if it gets too big. In your views:

如果管理器代码太大,请随意将其分隔在单独的文件中。在您的观点中:

# views.py

from accounts.models import Account

Account.objects.create_account(account, user_list)

The business logic is still in the models.

业务逻辑仍然在模型中。

EDIT

编辑

The keyword here is override, not overwrite. If you override the model's save method, you have to keep in mind that any create, update operations from within your web app and admin will use this new functionality. If you only want those business logic to happen once in a specific view, it might be best to keep it out of save.

这里的关键字是覆盖,而不是覆盖。如果您覆盖模型的保存方法,则必须记住,您的Web应用程序和管理员中的任何创建,更新操作都将使用此新功能。如果您只希望这些业务逻辑在特定视图中发生一次,则最好不要将其保存。

I guess you can put your business logic in its own regular class. You will have to instantiate that class each time you need to run your business logic. Alternatively, you can put your business logic as a static function in this new class if you want to skip the OOP approach.

我想你可以将你的业务逻辑放在自己的常规类中。每次需要运行业务逻辑时,都必须实例化该类。或者,如果要跳过OOP方法,可以将业务逻辑作为静态函数放在此新类中。

#2


2  

What I'm doing is that most of my apps have service.py file with business logic. This is because if I need a function that works with models from multiple apps I simply cannot do this:

我正在做的是我的大多数应用程序都有带有业务逻辑的service.py文件。这是因为如果我需要一个适用于多个应用程序模型的函数,我根本无法做到这一点:

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

This code will be stuck in circular reference loop.

此代码将卡在循环引用循环中。

But I'm gonna move most likely from service.py to app with structure like this:

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

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

#3


0  

Well the example that you illustrated above with the accountManager.createAccount(account, userList) seems like something that could be easily done my adding a createAccount method to the account model. If you feel the need to take business logic outside of the model though you could always just create a new module that host your business logic, and then import and used in in your views.

以上使用accountManager.createAccount(account,userList)说明的示例似乎可以通过向帐户模型添加createAccount方法轻松完成。如果您觉得需要在模型之外采用业务逻辑,尽管您可以随时创建一个托管业务逻辑的新模块,然后在视图中导入和使用。