详细摘要 摘要

生成:2025-06-21 18:54

摘要详情

音频文件
2024-07-11 | DjangoCon Europe 2024 | Modernizing CRUD Operations in Django
摘要类型
详细摘要
LLM 提供商
openai
LLM 模型
gemini-2.5-pro
温度
0.3
已创建
2025-06-21 18:54:46

概览/核心摘要 (Executive Summary)

本次演讲由开发者 Hicham Bakri 主讲,核心内容围绕他为解决 Django (特别是 Django Ninja) 大规模应用中 CRUD (创建、读取、更新、删除) 操作代码重复问题而开发的开源库 Django Ninja CRUD。Bakri 指出,传统方式下,为不同模型创建大量相似的 API 端点会导致代码冗余和不一致性风险。他的解决方案是引入一种声明式的、基于组件的接口来定义 API 视图。

该方案的核心是 APIViewAPIViewSet 两个类。APIView 将单个端点的逻辑(如路径、方法、处理函数)封装成可复用的组件。APIViewSet 则作为一个容器,通过类属性自动发现并注册其中定义的多个 APIView 组件,从而将相关端点聚合管理。这种方法极大地简化了代码,开发者仅需几行代码即可为一个模型生成一套完整的 CRUD 端点。其关键优势在于高度的灵活性和可组合性,例如,允许为同一模型轻松定义多个具有不同序列化结构(Schema)的列表视图。

此外,Bakri 还分享了他在优化测试体验方面的探索。他最初尝试将组件化思想应用于测试,但发现效果不佳。最终,他开发了另一个独立的库 Django Rest Testing,采用基于“场景 (Scenario)”的黑盒测试方法,将请求与预期响应封装起来,从而简化了测试用例的编写和管理。最后,他展望了 Django Ninja CRUD 的未来,包括增加异步视图支持、修复现有问题,并可能将其设计理念扩展到其他框架。

Django Ninja 的挑战与机遇

  • Django Ninja 简介与优势:

    • 演讲者 Hicham Bakri 首先肯定了 Django Ninja 带来的优秀开发者体验,特别是其基于 Pydantic 的便捷序列化和自动生成的 OpenAPI 文档。
    • 他个人尤其欣赏其抽象层次,它将序列化和反序列化操作提升到中间件层,使视图函数(view function)本身更加纯粹和简洁。
  • 面临的核心挑战:代码重复:

    • 在任何大型应用中,随着模型数量的增多,不可避免地会出现大量重复的代码。
    • Bakri 发现,即使业务逻辑被封装在服务层(Service Layer),在端点层(Endpoint Layer)的重复问题依然严重。
    • 他强调:> "重复的逻辑...当然会增加不一致的风险 (duplicated logic... increases, of course, the risk of inconsistencies)。"
    • 他认为 Django REST Framework 中的 ViewSets 等现有解决方案虽然有用,但在灵活性上有所欠缺,通常只允许“对每个视图有一种可能的实现 (one possible implementation of each view)”,无法满足他更灵活的需求。

核心解决方案:声明式的组件化视图

  • 设计理念与灵感:

    • 该想法诞生于一年前的假期,其核心是将 API 视图视为组件 (Components),借鉴了前端开发的模块化思想。
    • 目标是创建模块化、可复用的视图,以减少样板代码(boilerplate code)和开发过程中的挫败感。
  • 技术实现思路:

    1. APIView: 通过分析 Django Ninja 的源码,他设计了一个 APIView 类,用于将单个 API 操作的属性(如 path, method 等)和视图逻辑封装成一个独立的对象。
    2. APIViewSet: 这是一个容器类,它利用 Python 的元类特性(原文提及 insaclass,应指 __init_subclass__)来自动发现其内部定义为类属性的所有 APIView 实例。
    3. 自动注册: APIViewSet 会遍历这些 APIView 组件,并将它们动态地注册到 Django Ninja 的路由器(Router)上,从而实现了视图的自动分组和声明式定义。

Django Ninja CRUD 库详解

  • 基于 CRUD 的标准化:

    • 为了使抽象的组件化概念更易于理解和使用,Bakri 以业界公认的 CRUD 操作(创建、读取、更新、删除)作为基础,提供了预设的视图组件。
    • 这些预设组件包括 ListView, CreateView, ReadView, UpdateView, DeleteView
  • 核心优势与用法:

    • 代码极简: 开发者只需继承 APIViewSet 并指定模型(Model),即可用极少的代码为该模型生成一套完整的 CRUD 端点。
    • 高度的灵活性与组合性: 这是该库最关键的特性。开发者可以在同一个 APIViewSet 中多次使用同一种视图组件。
      • 示例: > "你可以多次使用列表视图。例如,你可以用一个简单的 schema 列出一个部门,用一个包含关联对象的扩展 schema 列出,还可以用一个只包含 ID 的简单 schema 列出。(you can use the list views several times. For example, you can list a department with a simple schema and an extended one with related objects and a simple one with just the ids.)"
    • 强大的可定制性:
      • 预设的视图组件提供了丰富的钩子(hooks)以便注入自定义业务逻辑,例如 pre_save, post_save, pre_delete, post_delete 等,用户无需重写整个视图。
      • 可以通过覆盖 init_model 等方法,处理复杂的路径参数或请求依赖。
    • 动态路径参数生成: 该库能够智能地解析 URL 路径中的参数,并与 Django 模型字段关联,从而在运行时动态生成 Pydantic schema。
  • 创建自定义视图:

    • 该库的设计初衷不仅限于 CRUD。用户可以轻松创建符合自己业务需求的、可复用的自定义视图。
    • 只需继承 APIView 基类,定义好接口和内部视图函数,然后将其作为类属性添加到 APIViewSet 中即可,无需修改 APIViewSet 的核心代码。

测试体验的现代化

  • 失败的尝试:

    • Bakri 最初尝试将组件化思想也应用到测试中,创建了所谓的“测试对象 (test objects)”。
    • 他很快发现这是一个错误的方向,因为它隐藏了测试细节,使得测试变得僵化,难以理解和维护。> "你可能根本不知道你正在测试什么 (You were not probably aware of what you were testing)。"
  • 新的解决方案:Django Rest Testing:

    • 他吸取教训,开发了一个名为 Django Rest Testing 的独立库。
    • 该库采用黑盒测试方法,引入了一个 Scenario 对象。
    • Scenario 对象封装了一次测试的输入(请求组件)和预期输出(响应断言)
    • 这种方法使得在一个测试函数中可以清晰地定义和运行多个完全隔离的场景(例如,使用不同权限的用户进行测试),极大地提高了测试的可读性和可维护性。

未来方向与结论

  • Django Ninja CRUD 的未来计划:

    • 近期修复: 解决 APIView 在输入参数上过于“固执己见 (opinionated)”的问题,增加对 headercookie 等参数的全面支持。
    • 功能增强: 实现社区呼声很高的功能,特别是对异步视图 (async views) 的支持。
    • 版本规划: 考虑发布 v1.0 版本。
    • 长远愿景: 探索将这种可组合的视图设计理念移植到其他框架的可能性,如 Django REST Framework 或 FastAPI,但这尚无明确计划。
  • 个人感悟与致谢:

    • Bakri 坦言,独立开发和维护这两个库是“非常耗时 (real time consuming)”的,但也是一次“非常有价值的学习经历 (really valuable learning experience)”。
    • 他最后感谢了所有为项目做出贡献的人、赞助商、GitHub、JetBrains 以及 DjangoCon Europe 的组织者。