type
status
date
slug
summary
tags
category
icon
password
Django REST Framework (DRF) 是一个基于Python的Django web框架的扩展库,用于构建优雅、功能丰富且易于使用的RESTful API。以下是对DRF框架的详细解析
简介与核心特性
DRF简介
DRF提供了丰富的工具和组件,使得开发者能够快速、高效地创建符合RESTful原则的API。这些API可以服务于各种客户端,包括但不限于浏览器、移动应用、物联网设备以及与其他服务的集成。DRF强调清晰的层次结构、统一的交互模式以及强大的文档支持,极大地简化了API的设计与实现过程
核心特性
- 序列化(Serialization):DRF提供了一套简洁的机制来定义数据模型到JSON或其他格式的序列化规则,以及反序列化过程。这使得模型对象能轻松转换为适合网络传输的格式,反之亦然
- 视图(Views):DRF提供了一系列基于类的视图,如ModelViewSet、APIView等,它们封装了常见的CRUD(创建、读取、更新、删除)操作逻辑,简化了API接口的编写
- 路由与URL配置:通过DRF的路由器,可以便捷地将视图与URL路径映射起来,自动处理资源的集合与单个实例的访问路径
- 认证(Authentication):内置多种认证方式,如基本认证、令牌认证、OAuth1/OAuth2等,可灵活配置以满足不同场景的安全需求
- 权限(Permissions):提供了细粒度的权限控制体系,确保只有经过授权的用户或客户端才能访问特定的API资源
- 分页(Pagination):内置多种分页器,轻松处理结果集的分页显示,避免一次性加载大量数据。
- 过滤(Filtering):支持字段查询、范围查询、关系查询等多种过滤方式,允许客户端灵活筛选API返回的数据。
- 版本控制(Versioning):支持API版本管理,确保向后兼容性和新特性的平滑引入。
- 响应与异常处理:提供了丰富的响应类和异常处理机制,使得API能够返回一致且易于理解的错误信息
- Browsable API:自带一个交互式的Web界面,使得API在开发阶段无需额外工具即可直观查看和测试。
RESTful API设计
RESTful原则
DRF遵循REST(Representational State Transfer)原则,即:
- 资源(Resources):每个URL代表一种资源,如用户、文章、订单等
- HTTP动词(HTTP Verbs):使用HTTP方法(GET、POST、PUT、DELETE等)表示对资源的操作,如GET获取资源、POST创建资源、PUT更新资源、DELETE删除资源。
- 状态转移(State Transfer):通过请求和响应间的交互,客户端和服务器共同维护资源的状态。
- 统一接口(Uniform Interface):所有资源的交互都遵循相同的接口约定,减少学习成本和复杂性。
DRF的主要组件
序列化器(Serializers)
序列化器负责将Python对象(如Django模型实例)转换为可序列化的数据格式(如JSON),以及反向操作。开发者可以通过继承serializers.ModelSerializer等基类并指定相关字段来快速定义序列化规则
1. 序列化器类
序列化器类通常继承自rest_framework.serializers.Serializer或rest_framework.serializers.ModelSerializer,并定义一系列字段来描述目标数据的结构。字段类型与Django模型字段类似,包括但不限于:
- 字符串字段:CharField、TextField
- 数值字段:IntegerField、FloatField、DecimalField
- 布尔字段:BooleanField
- 日期/时间字段:DateField、DateTimeField
- 关系字段:ForeignKey、ManyToManyField、OneToOneField(需使用PrimaryKeyRelatedField、SlugRelatedField、HyperlinkedRelatedField等)
- 复合字段:ListField、DictField、NestedSerializer(用于嵌套对象)
- 文件字段:FileField、ImageField
2.基础序列化器类(Serializer)
基础序列化器类 rest_framework.serializers.Serializer 是最基础的序列化器类型,用于处理非模型对象的序列化与反序列化。通常需要手动定义类属性fields或exclude来指定要序列化的字段及其类型。
示例
3. 模型序列化器类(ModelSerializer)
在这个例子中:
- UserModelSerializer继承自ModelSerializer,并指定了关联的模型类User。
- Meta类内部定义了序列化器的元数据,包括要序列化的字段列表和只读字段列表。
4. 序列化器方法
序列化器类提供了以下主要方法:
- serialize(obj, *, fields=None, **kwargs): 将给定的对象obj序列化为字典。可选参数fields用于指定要序列化的字段子集。
- to_representation(instance): 实现将序列化器实例(与模型实例关联)转换为字典的逻辑。这是序列化过程的核心方法,通常由框架自动调用。
- to_internal_value(data): 将外部数据(如请求体中的JSON)反序列化为Python字典。这是反序列化过程的核心方法,通常由框架自动调用。
- is_valid(raise_exception=False): 验证输入数据的有效性,返回布尔值表示验证结果。若raise_exception=True,验证失败时抛出异常。
- save(**kwargs): 在验证数据通过后,保存或更新模型实例。对于非模型序列化器,可能需要自定义此方法以实现数据持久化。
5.字段选项
序列化器字段支持多种选项以定制行为:
- read_only: 标记字段为只读,反序列化时忽略此字段。
- write_only: 标记字段为只写,序列化时忽略此字段。
- required: 指定字段是否为必填项。在反序列化时,若未提供必填字段的值,将引发验证错误。
- allow_null/allow_blank: 控制字段是否允许为空值或空字符串。
- validators: 为字段添加自定义验证器列表。
- error_messages: 定义字段特定的错误消息。
6. 关系字段
处理模型之间的关系时,使用以下特殊字段:
- PrimaryKeyRelatedField: 通过主键关联另一个模型。
- SlugRelatedField: 通过模型的slug字段关联另一个模型。
- HyperlinkedRelatedField: 返回关联对象的URL,而非直接的关联数据。
- ManyRelatedField/ManyToManyField: 处理多对多关系。
- NestedSerializer: 对嵌套对象使用单独的序列化器进行序列化和反序列化。
7. 示例
序列化模型实例:
反序列化请求数据:
8.结论
Django REST Framework的序列化器为API开发提供了强大的数据转换能力,简化了模型对象与JSON等网络传输格式之间的相互转换。通过合理使用序列化器类、字段选项以及关系字段,可以高效地构建结构清晰、验证严谨的API接口
9.局部钩子和全局钩子
在需要对单个字段进行自定义校验的时候,可以在序列化类中写入对应的校验方法,然后通过自带的异常模块返异常
10.serializer高级使用,展示关联字段的详细信息
1 source 字段的作用
- book name=serializers.CharField(source="name"
- source 可以对应表模型的字段和方法(返回结果是什么,字段就是什么),表模型中写的方法-一般用来做一对 多,多对多的字段返回
2 SerializerMethodField
使用方法如下

- 方式一 ,类模型中修改

- 方式二 SerializerMethodField

11.serializer多表关联的展示与保存
- 序列化展示

- 反序列化保存

12.自定义钩子,序列化和反序列化针对同一个字段展示

可以将重写的方法封装一个类,然后继承


执行看到 序列化和反序列化现实的字段都是一样,并且序列化已经对字段关联的字符串做了转义
视图(Views)
DRF视图基于Django的CBV(Class-Based Views),但专为API开发进行了优化。常见的视图类如ModelViewSet提供了完整的CRUD操作,只需少量配置即可完成复杂的API逻辑。视图中通常会结合使用序列化器进行数据处理。
在Django REST Framework (DRF) 中,视图类(View Classes)是构建API的核心组件之一,它们封装了处理HTTP请求、执行业务逻辑、返回响应等任务。DRF提供的视图类基于Django的Class-Based Views(CBVs),并针对RESTful API的开发进行了深度定制和扩展。以下是DRF视图类的详细解析
1.视图类层次结构
DRF的视图类形成了一个层次结构,其中基础类rest_framework.views.APIView是最底层的抽象,其他视图类通常继承自它或其子类。主要的视图类层次如下
APIView
├── GenericAPIView
│ ├── ListAPIView
│ ├── RetrieveAPIView
│ ├── CreateAPIView
│ ├── UpdateAPIView
│ ├── DestroyAPIView
│ ├── ListCreateAPIView
│ ├── RetrieveUpdateAPIView
│ ├── RetrieveDestroyAPIView
│ ├── RetrieveUpdateDestroyAPIView (相当于ModelViewSet)
└── ViewSet (用于ViewSet类的通用方法,如`list()`、`retrieve()`等)
└── ModelViewSet (最常用的视图类,封装了完整的CRUD操作)
2. APIView
基础视图类 APIView 是最基础的视图类,它直接继承自Django的View类。APIView实现了对HTTP方法的映射(如get(), post(), put(), delete()等)以及一些通用的API处理逻辑,如内容协商、认证、权限检查、异常处理等。开发者可以直接使用APIView编写自定义视图,但对于大多数RESTful API来说,更推荐使用更上层的通用视图或视图集
3.GenericAPIView
通用视图类 GenericAPIView 继承自APIView,增加了对序列化器(Serializer)、查询集(QuerySet)管理、分页(Pagination)、过滤(Filtering)等功能的支持。它定义了一些抽象方法,如get_serializer_class()、get_queryset()等,供子类覆盖以实现具体的业务逻辑。使用GenericAPIView或其子类可以显著减少重复代码,提高开发效率
4.基于动作的视图类
基于动作的视图类进一步细化了GenericAPIView的功能,针对特定的HTTP动作(如获取列表、获取单个实例、创建、更新、删除等)提供了专门的视图类。这些视图类包括:
- ListAPIView: 仅处理GET请求,返回资源列表。
- RetrieveAPIView: 仅处理GET请求,返回单个资源实例。
- CreateAPIView: 仅处理POST请求,用于创建新的资源实例。
- UpdateAPIView: 仅处理PUT/PATCH请求,用于更新单个资源实例。
- DestroyAPIView: 仅处理DELETE请求,用于删除单个资源实例。
- ListCreateAPIView: 同时处理GET(获取列表)和POST(创建资源)请求。
- RetrieveUpdateAPIView: 同时处理GET(获取单个实例)和PUT/PATCH(更新资源)请求。
- RetrieveDestroyAPIView: 同时处理GET(获取单个实例)和DELETE(删除资源)请求。
- RetrieveUpdateDestroyAPIView: 同时处理GET、PUT/PATCH、DELETE请求,实现完整的CRUD操作。
5.MinIn混合类
对混合类再次封装
6.ViewSet(对请求方式分发的重新构建)
视图集类 ViewSet 是一种更高级别的抽象,它将多个相关的视图类(如ListAPIView和RetrieveAPIView)组合在一起,形成一个逻辑上的集合。视图集通过方法命名约定(如list()、retrieve()、create()等)来对应不同的HTTP动作。视图集不直接处理请求,而是由其内部的路由和视图分发器(如@action、@link装饰器,以及DefaultRouter)负责将HTTP请求映射到相应的方法上
urls.py
上述 需要配合generic视图类,和minin混合类来进行代码的优化
url.py
7.ModelViewSet
模型视图集类 ModelViewSet 是最常用的一种视图集,它继承自ViewSet,并针对Django模型对象进行了深度定制。ModelViewSet已经实现了完整的CRUD操作,只需配置好模型、序列化器和权限等相关信息,即可快速创建出一套完整的RESTful API。使用ModelViewSet时,通常配合DRF的DefaultRouter自动为视图集生成对应的URL路由
路由器(Routers)
路由器用于自动为视图生成对应的URL配置,支持基于资源名称的嵌套URL结构,简化了URL管理和客户端导航
认证与权限
DRF提供了多种认证类,如TokenAuthentication、SessionAuthentication等,可以通过配置DEFAULT_AUTHENTICATION_CLASSES选择使用。权限控制则通过设置DEFAULT_PERMISSION_CLASSES来启用,如IsAuthenticated、DjangoModelPermissions等。
简单认证功能开发
需求,用户登录成功写入一个token,每次登录都会刷新这个token,当用户访问某个接口时候,需要登录才可以访问
- models.py
- views.py
- serializers.py
- auth.py 封装用户认证的类
- 接口关联用户类


将token写入headers中

认证类全局使用,和局部禁用
现在想把自定义的认证类在全部生效,就不用在每个视图类下面写authentication_classes
setting.py中添加
接口视图

需要认证的接口可以去除authentication_classes
认证通过之后的返回值


如果有多个认证类,则最后一个返回user和auth 其他返回None
权限配置
- 权限类配置
- 视图引用


自定义权限异常信息


频率限制
在Django REST Framework (DRF) 中,频率限制是通过throttling模块实现的,用于控制API的调用速率,以防止滥用或DDoS攻击。DRF提供了多种内置的节流类,可以根据需要选择合适的策略。以下是一些关键概念和内置节流类的简要说明
BaseThrottle:
这是所有节流类的基础,定义了基本的行为和接口。
AnonRateThrottle:
限制匿名用户的请求速率。默认情况下,它限制每个IP地址的请求速率。
UserRateThrottle:
限制已认证用户(通过session或token)的请求速率。对于同一用户,无论他们使用多少个IP地址,都会受到限制。
SimpleRateThrottle:
最简单的节流实现,基于时间窗口(如每分钟、每小时)限制请求次数。可以设置rate参数来定义速率,如'10/hour'表示每小时最多10次请求。
ScopedRateThrottle:
允许根据资源的不同部分(如URL路径的一部分)设置不同的速率限制。
设置节流类:
在你的settings.py文件中,通过REST_FRAMEWORK字典配置节流类。例如,全局设置匿名和用户速率:
或者,你可以在特定视图或视图集上设置自定义的节流类
自定义节流类:
如果内置的节流类不能满足需求,你可以创建自己的节流类,继承自SimpleRateThrottle,并覆盖get_cache_key方法来实现自定义逻辑
- 继承原有的类,重写get_cache_key方法
- setting中配置 scope标识
- 视图类中应用频率类


分页与过滤
通过在视图中设置pagination_class和filter_backends属性,可以启用分页器(如PageNumberPagination)和过滤器(如SearchFilter、OrderingFilter),实现数据的分页展示和客户端驱动的筛选
过滤、排序


- 视图类必须继承GenericAPIView
分页
继承分页类
配置文件配置每页显示条数

版本控制
DRF支持多种版本控制策略,如URL路径版本、请求头版本等。通过配置DEFAULT_VERSIONING_CLASS选择合适的版本控制方案,并在视图或全局配置中定义版本间的行为差异
JWT
在 Django REST Framework (DRF) 中集成 JWT 认证,通常推荐使用 djangorestframework-simplejwt,因为它比旧的 djangorestframework-jwt 更活跃且功能更丰富。下面是安装和基本使用的步骤
安装 djangorestframework-simplejwt
首先,确保你已经安装了 Django REST Framework。然后,通过 pip 安装 djangorestframework-simplejwt:
Simple JWT的默认设置
添加到 INSTALLED_APPS
配置 JWT 设置
在 settings.py 中,添加 JWT 相关的设置。这包括定义密钥、调整过期时间等
全局配置
用户认证视图
对于用户登录,你可以直接使用 djangorestframework-simplejwt 提供的视图,或者自定义视图来处理用户验证和令牌生成。最简单的做法是直接在你的 urls.py 中包含这些视图:
请求认证
获取令牌:客户端通过 /api/token/ 发送包含用户名和密码的 POST 请求,以获取访问令牌和刷新令牌。
使用令牌:在后续请求的 HTTP 头部中加入 Authorization: Bearer <your_access_token>。
刷新令牌:当访问令牌过期时,客户端可以使用 /api/token/refresh/ 和刷新令牌来获取新的访问令牌。
- 视图配置一定要加上 权限类,作为局部认证
- 登录,返回token

- 拿到token,进行其他url访问,需要卸载请求头上,key为Authorization,value的值前面必须是Bearer +空格+token 可以在配置文件中自定义更改

自定义登陆成功后返回的数据格式
在上述登录成功之后返回的默认格式如下:

现在想要修改返回格式,加上自定义个的一些内容,可以查看源码,这个返回格式是在rest_framework_simplejwt.serializers.TokenObtainPairSerializer 这个文件下的类中,查看这个类,并且在jwt的setting中引用了


所以,只需要重写这个类,然后再我的应用setting中引用自己写的类即可
- app01/serializers.py
- settings.py

再次请求,已经得到自定义的返回格式
自定义token的payload信息


自定义 JWT认证类
重写JWT认证类方法,规定请求头的token 直接是原token,前面不携带任何字符串

注意源码中的self.user_model 这里可以直接改成django的auth表中的User表

视图类中引用即可

自定义登录和认证(多方式登录auth_user表)
基于自定义表签发token
- urls.py
- 序列化类编写,主要用于校验,生成token(直接继承jwt的生成token的类)
- 视图类编写

基于自定义表编写token认证类
在上面基于auth.User表的认证类基础上,修改下user表就可以了,最后在视图类中应用即可

需要注意的是:
validated_token.payload 返回的是解码后的明文payload数据
每次接口都会访问数据库,这里可以直接实例化一个对象,将user_id传入,后续操作只使用id就够了 user = UserInfo(pk=user_id)
- Author:dittoyang
- URL:https://blog.yangziyang.top/article/42355397-0542-4f90-9f73-033eecc5135a
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!