Django-CSR架构总结Rest framework
这篇讲什么
- 这篇从架构视角看 DRF:前后端分离(CSR)要解决什么问题、一次请求在 DRF 里怎么从路由走到序列化器再变成 JSON、以及「四行代码定义一个模型的 API」到底成不成立。
- 涉及的组件行为都按本机 Django 5.2.19 + DRF 3.18.3 实测过。
解决什么问题
- 给应用提供 RESTful API:前端(Vue/React/小程序)只管展示,后端只管数据与业务,两边靠 JSON 接口通信。
- 这里的 CSR 指 Client-Side Rendering(客户端渲染),与 SSR(服务端渲染)相对:页面骨架由前端出,数据由 API 给。
DRF 架构之美
- 简单易用:既可以用自动 CRUD(
ModelViewSet+Router),也可以自定义单个接口。 - 提供可浏览的 HTML API(
BrowsableAPIRenderer)。 - 一套实现同时提供 HTML / JSON 两种表现层(实测
Accept协商与格式后缀,见《Django-RESTful-Api之请求与响应》)。 - 灵活的认证:Session / Basic / Token 内置,OAuth、JWT 走第三方(实测 JWT 不在 DRF 本体里)。
- 权限可组合:
AllowAny、IsAuthenticated、IsAuthenticatedOrReadOnly、Django 模型权限、自定义BasePermission,还有 3.10 起的AND/OR/NOT。 - 自带过滤、搜索、排序、分页、版本控制、限流、文档(文档要靠
drf-spectacular)。
「四行代码定义一个模型的 API」到底行不行
-
老笔记那段的代码是错的(
viewsets.ModelviewSet、Userserializ都是笔误)。修正后实测确实能跑:school/views.py 1
2
3
4
5
6
7
8
9
10
11
12
13from django.contrib.auth.models import User
from rest_framework import serializers, viewsets
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = ["url", "username", "email", "is_staff"]
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializerschool/urls.py 1
2
3
4
5from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register(r"users", UserViewSet)
urlpatterns = [path("", include(router.urls))]-
实测生成的路由:
user-list=^vs/users/$、user-detail=^vs/users/(?P<pk>[^/.]+)/$,GET列表 200。 -
但超链接序列化器有前置条件(实测):路由必须能被反解。应用
urls.py里写了app_name时,view_name要带上命名空间,否则整个接口 500:1
2ImproperlyConfigured: Could not resolve URL for hyperlinked relationship using view name
"user-detail". You may have failed to include the related model in your API, or ...
所以「四行」只在没有命名空间、没有权限要求时成立;真实项目还要加认证、权限、分页、过滤四件套(各见对应文章)。
-
一次请求在 DRF 里走过的路


- URL 分发:
DefaultRouter生成的URLPattern命中,as_view({"get": "list", ...})把 HTTP 方法映射到 ViewSet 动作。 - 请求包装:
HttpRequest→ DRFRequest,request.data由JSONParser/FormParser/MultiPartParser解析(实测 Content-Type 不支持时 415)。 - 认证:按
authentication_classes依次尝试,request.user/request.auth被填上(实测默认只有 Session + Basic)。 - 权限:
permission_classes全过才继续;对象级权限在取到对象后再查has_object_permission(实测列表接口不会走它)。 - 过滤/排序/分页:
filter_queryset()→paginate_queryset()(实测不显式挂后端时这些参数全被忽略)。 - 序列化:
get_serializer()→.data(ReturnDict/ReturnList)或.errors。 - 响应与协商:
Response交给DefaultContentNegotiation选渲染器(实测Accept: text/html得到可浏览页面,application/xml得到 406)。 - 异常:任何
APIException都过exception_handler,形状统一成{"detail": ...}或字段错误字典。
整体架构与配套件
| 层次 | 组件 | 本机版本 | 对应文章 |
|---|---|---|---|
| 路由 | DefaultRouter / SimpleRouter |
DRF 3.18.3 | 《Django-RESTful-Api之ViewSets和Routers》 |
| 视图 | ViewSet / generics / APIView |
同上 | 《Django-RESTful-Api之基于类的视图》 |
| 序列化 | ModelSerializer / HyperlinkedModelSerializer |
同上 | 《Django-RESTful-Api之序列化》 |
| 认证权限 | TokenAuthentication / IsOwnerOrReadOnly |
同上 | 《Django-RESTful-Api之认证和权限》 |
| 过滤 | DjangoFilterBackend + SearchFilter + OrderingFilter |
django-filter 26.2 | 《Django-RESTful-Api设计风格》 |
| 分页 | PageNumber / LimitOffset / Cursor |
DRF 内置 | 同上 |
| 文档 | drf-spectacular(OpenAPI 3.0.3) |
0.30.0 | 《Django-常用插件》 |
| 缓存/异步 | 内置 Redis 缓存、Celery | redis 8.1.0 / celery 5.6.3 | 《Django-缓存》《Django-Celery》 |
| 部署 | WhiteNoise + Gunicorn/uvicorn + Nginx | 6.12.0 / 26.2.0 / 0.54.0 | 第四批(部署与运维) |
参考
- Django REST framework 教程:Quickstart:四行 CRUD 的官方版本。
- Django REST framework:API Guide:请求生命周期涉及的每个模块。
- drf-spectacular 文档:OpenAPI 生成与视图挂载。
- MDN:Client-side rendering (CSR) vs Server-side rendering (SSR):CSR 这个名词的准确含义。