【问题标题】:Django Rest Framework Business LogicDjango Rest 框架业务逻辑
【发布时间】:2015-07-23 17:25:57
【问题描述】:

我正在尝试使用 Django Rest Framework 创建一个后端,并尝试确定将业务逻辑放置在何处。它会进入views.py吗?我想创建更复杂的服务,而不仅仅是获取对象列表或抓取一个特定对象。任何指导将不胜感激,谢谢。我意识到有一个关于通用 Django 项目中业务逻辑的讨论,但我专门询问 django rest 框架。

【问题讨论】:

  • 关于这个已经有很大的讨论了:stackoverflow.com/questions/12578908/…
  • 是的,我看过那个,但希望能具体询问一下 django rest 框架中的位置
  • 你找到适合这个的设计模式了吗?谢谢

标签: python django django-rest-framework business-logic


【解决方案1】:

更多的是关于设计模式而不是 Django Rest 框架。

这里有一些提示:

  • 使用 REST 提供接口不应涉及任何与数据操作或业务逻辑相关的特定代码。
  • 使用 MVC 方法并不意味着您不应该对应用程序进行分层。
  • 您应该能够在完全不接触 UI 的情况下测试业务逻辑。
  • 有些人可能会建议将业务逻辑放入模型中。但我不同意他们的观点,因为 Django 模型不同于域模型和与业务相关的任务,例如税收计算。
  • 在陷入 MVC 之前,您可以阅读有关 The MVC implemented in MVC three-tier architecture 的更多信息
  • 我建议有一个业务层和相关应用程序将您的业务逻辑放在那里。

假设您有一家在线咖啡店,并且您想提供一个 REST API 来订购咖啡。

这是我建议的代码示例:

myapp/views.py:

    def order(request, quantity=1):
        # Process the order by calling the mapped method
        order_id = CoffeeShopService.place_order(quantity)
        return HttpResponse({'order_id': order_id, mimetype='application/json')

myapp/services.py:

    class CoffeeShopService(object):
        @staticmethod
        def place_order(quantity):
           # do the business logic here
           return order_id

【讨论】:

  • 感谢您的洞察力。但是通过实施您的想法,我还有另一个问题。我很难标准化我的异常处理。如您所知,在 DRF 我们有ValidationError。在viewsets 中也有另一个异常,比如我们在模型中有很多异常类。问题是那些错误处理在 API 响应中有不同的格式。
  • DRF 中的异常处理是一个不同的问题,可以通过自定义异常处理来解决。如果你搜索,你可以找到如何做,或者你可以问一个单独的问题
  • 我最近开始在PythonDjango 中编码,在我编码到Java/Spring Boot 之前。我非常同意您的观点,即拒绝将逻辑放入models.py 使其更胖。在我看来,services 模块是制作一些业务流程的最佳场所。我只是从Spring Boot经验中得到的
【解决方案2】:

我猜这是一种设计模式 Questing in Rest Framework。这是我如何在基于 Rest Framework 的 API 构建中使用分层方法的详细概述!

为了便于维护,它更加分层,最重要的是利用了设计模式和 GRASP Principal!

分层方法包级视图

进一步分类:

现在是我如何通过层的示例:

  1. 向 example.com/Customer/profile 发出请求 @project/urls.py

  2. 请求被转发到相应 URL 的层 (@app/urls/Customer_Url)

  3. URL 将其传递给相应的视图集 (@app/Viewsets/Customer_Viewsets/Customer_Signup.py)

  4. 它是一个发布请求,(我假设在这个例子中)被转发到业务逻辑层 (@app/BusinessLogicLayer/BLL.py)

  5. 业务逻辑层有一个抽象实现(充当 IBLL 的接口),它将请求转发到相应的方法以检查我的所有业务规则! (@app/BusinessLogicLayer/SUB_BLL/客户/*)

  6. 然后将请求转发到数据访问层,该层将用户的数据存储在数据库中。等等! (@app/DataAccessLayer/DAL.py)

【讨论】:

  • Customer_Name is "" -- 这是完全错误的。通常代码有异味。您应该使用验证框架(例如 Marshmallow)。
  • 我基本上是在设置一个空字符串来处理我的一些自定义事物,这个 API 是由几十个设备交互的!此外,此代码是我的团队成员的工作,因此他更好地证明它,我的主要目标是概述分层架构。如果不是 Customer_Name,我自己会使用 :)
  • @warvariuc 如果您能选择架构方面的错误,我将不胜感激,因为我自己更专注于长期使用它,所以我真的很想解决我在架构方面的错误。最重要的是,非常感谢:)
  • 当使用驼峰式命名、重复代码、错误的低级习语时,很难判断架构。还有太多的信息和截图而不是文字。国际海事组织。我也只看到代码和解释,但没有描述代码中使用的设计原则。
  • @warvariuc 目前,我正在学习学生,仅完成了 1 年的软件工程,还有 3 年的学习时间:)。我支持自己直到这个级别:) 如果我们可以通过电子邮件或 Skype 交流,是否愿意从您的知识中学习和成长?
【解决方案3】:

也许这是一种有点古怪的方式,但我认为通过在其中添加方法将逻辑包装到序列化器中非常有帮助。

例如

序列化器:

class OrderSerializer(serializers.ModelSerializer):
    class Meta:
        model = Order
        fields = (
            'id',
            'total',
            'discount',
        )

    def calculate_discount(self, whatever_params):
        # calculate discount if you need... and return it

    def calculate_tax(self, whatever_params):
        # calculate tax amount if you need...and return it

    def calculate_grand_total(self, whatever_params):
        # calculate grand total if you need and return it

    def create(self, validated_data):
        # You can make an order by applying 
        # some logic in the calculation method.
        # Maybe by adding a bit of the context 
        # you sent as parameters from view.

【讨论】:

  • 即使可以做到,我认为将逻辑放入serializers 并不明显和错误。由于序列化器的主要思想只是简单地对数据进行序列化和反序列化并制作一些验证人员。在django 项目架构方面是不正确的。
猜你喜欢
  • 2019-02-12
  • 1970-01-01
  • 2021-04-10
  • 2011-04-15
  • 2013-09-14
  • 2012-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多