【问题标题】:Django rest framework where to write complex logic in serializer.py or views.py?Django rest框架在serializer.py或views.py中哪里写复杂的逻辑?
【发布时间】:2019-08-07 14:20:26
【问题描述】:

我是 Django Rest 框架的新手。使用 serializerviews 一个简单的 CRUD 很容易。当逻辑增加时,在serializerviews 中写逻辑的位置相当混乱。
一些开发人员确实更喜欢“厚序列化程序和精简视图”,而一些开发人员更喜欢“厚视图和精简序列化程序”。
也许这不是一个大问题,我认为是否在viewsserializer 上写更多内容取决于开发人员,但作为新手,您有什么建议可以遵循?我应该在viewsserializer 上写更多吗?
Django View Template 上有很多答案,但找不到 Django Rest Framework 的满意答案。
经验丰富的开发人员的想法将受到高度赞赏。谢谢。

【问题讨论】:

    标签: django rest serialization django-rest-framework django-views


    【解决方案1】:

    我个人更喜欢将业务逻辑与视图和序列化程序分开。我通常创建一个具有业务逻辑的新类,该类可以根据需要在序列化程序和视图中使用。基本上我把它当作一种服务。原因是:

    1. 使代码更干净(没有厚薄的东西)。
    2. 为这些业务逻辑编写测试更容易。
    3. 您可以根据需要在视图和序列化程序中使用该业务逻辑服务。
    4. 在测试 API 时,您可以根据需要模拟这些业务逻辑。
    5. 在多个地方重用任何逻辑。

    一个例子是这样的:

    class BusinessLogicService(object):
    
        def __init__(self, request):
           self.request = request
    
        def do_some_logical_ops(self, data_required_one, data_required_two):
            # do processing
            return processed_data
    

    序列化程序中的示例用法:

    class SomeSerializer(serializer.Serialize):
         ...
         def create(self, validated_data):
             business_logic_data = BusinessLogicService(self.request).do_some_logical_ops(**validated_data)
             return Model.objects.create(**business_logic_data)
    

    【讨论】:

    • 从现在开始,我会尽量听从你的建议,解释得很清楚。什么样的逻辑最适合views,什么样的逻辑适合serializer
    • 这取决于您的应用程序设计。一般来说,您可以将验证相关的业务逻辑和数据操作放在序列化程序中。视图中的流量限制、权限、外部 api 调用等 :)
    • 你太棒了,解释得多么清楚。谢谢你。 :)
    • BusinessLogicService(self.request) 这里 serializer object has no attribute'request' 我错过了什么?
    • 您没有使用通用视图,或者您需要手动将请求对象从视图发送到序列化程序
    【解决方案2】:

    我之前就这个问题问过类似的question。实际上,这取决于您要适应的逻辑。在做了进一步的研究之后,我想出了一些方法。以下是我的建议:

    1. 如果您想在执行序列化程序验证之前添加一些逻辑,最好将其包含在您的视图中(例如,覆盖您的视图create 方法)。这种情况的一个例子是;您的 POST 正文不包含序列化程序所需的值,因此还无效,因此请将其添加到视图的 create 函数中。
    2. 如果您正在执行一些自定义身份验证逻辑,例如在您的 http 标头中解析自定义令牌,请在您的视图中执行此操作,因为序列化程序与它无关。此外,您可以为此创建自己的身份验证装饰器。
    3. 如果您想添加与数据表示直接相关的逻辑,例如将时间戳从 UTC 调整为其他逻辑,您可以在序列化程序中添加,因为它与您的对象表示直接相关。您可以使用SerializerMethodField 等来执行此操作。

    【讨论】:

    • 好的,知道了,如果viewserializer 都适用相同的逻辑,你会选择哪一个?
    • 您可以将它们放在您想要的任何位置。实际上,就像@ruddra 的回答一样,您可以在单独的实用程序或助手类中做到这一点。这也将起作用。但我更喜欢在视图或序列化器中添加与视图相关或与序列化器相关的逻辑。当我有诸如调用其他一些 Web 端点等逻辑时,我会创建单独的类。
    • 知道了,感谢您的帮助。谢谢。
    【解决方案3】:

    我尝试根据上下文的要求对其进行隔离。喜欢:

    • 如果我应该处理request 对象(如当前用户),我会尝试在view 中实现它。
    • 如果我需要处理查询模型来创建视图,我会切换到 serializer

    这也可能取决于我打算如何维护代码(如果我在单个文件中有大量视图,我会尽量避免实现逻辑内容)。

    【讨论】:

      猜你喜欢
      • 2018-03-22
      • 2015-07-23
      • 2021-04-10
      • 2014-10-10
      • 1970-01-01
      • 2011-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多