gpt4 book ai didi

python - Django Rest Framework 中模型方法中的业务逻辑在哪里?

转载 作者:太空狗 更新时间:2023-10-29 21:20:46 24 4
gpt4 key购买 nike

我有 3 个相互关联的模型,具有一对多关系。

  • 模型 A 可以有多个模型 B 的实例。
  • 模型 A 可以有许多模型 C 的实例。
  • 模型 B 可以有许多模型 C 的实例。

想法是,用户将创建模型 A 的实例(如股票投资组合),然后输入股票持有量(模型 C)。模型 B 适合的地方是我想根据投资组合(模型 A)中的股票(模型 C)运行计算/逻辑,并使用另一个类/模型来跟踪事情让生活更轻松,因此模型 B。

我最初在 Django View 中有这些计算的逻辑,但在 Two Scoops of Django 中读到业务逻辑应该与 View 分开。因此,我将逻辑移至模型 A(投资组合)的方法,现在从 View 中调用该方法。此逻辑循环遍历股票持有量并创建模型 B 的新实例,即结果。

我现在有兴趣探索 django-rest-framework 来为 javascript 前端(如 Angular)提供 API。我猜我将无法在我的 REST 界面中进行这种数据操作。但是,此逻辑的结果(模型 B 中的数据)需要通过 REST 可见。因此,这种计算/逻辑去哪里了?

最佳答案

Django Rest Framework 的主要部分是 View (ViewSets、ApiViews 等)和序列化器。这些都不是编写逻辑的理想场所。正如您提到的,在任何 View 中编写逻辑都不好。为什么?

  1. 无法在应用的另一部分使用相同的逻辑
  2. 没有办法封装逻辑(你需要为逻辑运行)
  3. 无法对逻辑进行单元测试,因为它与 View 相结合

恕我直言,模型不是编写逻辑的好地方。将模型视为您的数据库定义。我会让它们尽可能简单。您可以覆盖“保存”和其他方法来完成琐碎的任务。任何其他高级功能都应该存在于它之外。

我可以想到两个更好的地方来满足您的需求:

其中一个是 django signal

更好的是自定义类。在你自己的类中封装/解耦逻辑(你可以使用静态方法或实例方法,没关系),然后你将能够:

  1. 对这些方法进行单元测试/模拟该类
  2. 在别处重用这个逻辑
  3. 根据 KISS 简化您的代码原则
  4. 从保持信号代码简单的信号中使用它
  5. 在 celery 任务中使用它(如果您将来实现它)而无需修改一行代码

更新如何组织代码的示例。

From the comments it´s clear that a signal wouldn´t work because the analysis operation will run on user request. A signal would be useful if that operation should run automatically when saving an specific model.

I´m assuming you know how to use django-rest-framework api views orviewsets, serializers, etc. I you don´t how about that, better askanother question. This is going to be more a python explanation than anything else

在您的应用程序模块中,创建一个文件 app_business_logic.py 或您想要的任何名称。例如,您可以将它放在与 models.py 相同的级别,但这不是强制性的:

class HoldingsAnalyser:
# static method sample. Call it like this: "HoldingsAnalyser.run(..)"
@staticmethod
def run(holding_list):
# do your model generation here or whatever you need
return True # or whatever you need to return

# instance method sample. Create an instance first and then call the method:
# analyser = HoldingsAnalyser()
# analyser.run(...)
def run(self, holding_list):
# do your model generation here or whatever you need
return True # or whatever you need to return

现在,在 django-rest-framework api View 或 View 集中,创建一个 POST 方法,当客户端应用程序用户按下按钮(生成分析的按钮)时调用:

from yourapp.app_business_logic import HoldingsAnalyser

class StockPortfolioViewSet(WhatEverMixingYouNeedToInheritFrom):
serializer_class = whatever # look at the docs

@detail_route(methods=['post'])
def run_analysis(self, request, pk):
stock_portfolio = get the object based on the pk
holdings = make your query to get the holdings
analysis_result = HoldingsAnalyser.run(holdings)
if analysis_result:
# everything ok
return Response(status=status.HTTP_204_NO_CONTENT)
else:
return Response(a useful error for your client)

此 url 类似于 http://server.com/api_path/stockportfolio/21/run_analysis/,其中 21 是 StockPortfolio 的 ID

关于python - Django Rest Framework 中模型方法中的业务逻辑在哪里?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35508064/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com