drf
00 min
2024-5-14
2024-5-20
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
使用方法如下
notion image
  • 方式一 ,类模型中修改
notion image
  • 方式二 SerializerMethodField
notion image

11.serializer多表关联的展示与保存

  • 序列化展示
      notion image
  • 反序列化保存
      notion image

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

notion image
可以将重写的方法封装一个类,然后继承
notion image
notion image
执行看到 序列化和反序列化现实的字段都是一样,并且序列化已经对字段关联的字符串做了转义

视图(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 封装用户认证的类
- 接口关联用户类
notion image
notion image

将token写入headers中

notion image

认证类全局使用,和局部禁用

现在想把自定义的认证类在全部生效,就不用在每个视图类下面写authentication_classes
setting.py中添加
接口视图
notion image
需要认证的接口可以去除authentication_classes

认证通过之后的返回值

notion image
notion image
如果有多个认证类,则最后一个返回user和auth 其他返回None

权限配置

  • 权限类配置
  • 视图引用
notion image
notion image

自定义权限异常信息

notion image
notion image

频率限制

在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标识
  • 视图类中应用频率类
notion image
notion image

分页与过滤

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

过滤、排序

notion image
notion image
  • 视图类必须继承GenericAPIView

分页

继承分页类
配置文件配置每页显示条数
notion image

版本控制

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

自定义登陆成功后返回的数据格式

在上述登录成功之后返回的默认格式如下:
notion image
现在想要修改返回格式,加上自定义个的一些内容,可以查看源码,这个返回格式是在rest_framework_simplejwt.serializers.TokenObtainPairSerializer 这个文件下的类中,查看这个类,并且在jwt的setting中引用了
notion image
notion image
所以,只需要重写这个类,然后再我的应用setting中引用自己写的类即可
  • app01/serializers.py
  • settings.py
      notion image
再次请求,已经得到自定义的返回格式

自定义token的payload信息

notion image
notion image

自定义 JWT认证类

重写JWT认证类方法,规定请求头的token 直接是原token,前面不携带任何字符串
notion image
注意源码中的self.user_model 这里可以直接改成django的auth表中的User表
notion image
视图类中引用即可
notion image

自定义登录和认证(多方式登录auth_user表)

基于自定义表签发token

  • urls.py
  • 序列化类编写,主要用于校验,生成token(直接继承jwt的生成token的类)
  • 视图类编写
notion image

基于自定义表编写token认证类

在上面基于auth.User表的认证类基础上,修改下user表就可以了,最后在视图类中应用即可
notion image
需要注意的是:
validated_token.payload 返回的是解码后的明文payload数据
每次接口都会访问数据库,这里可以直接实例化一个对象,将user_id传入,后续操作只使用id就够了 user = UserInfo(pk=user_id)
上一篇
OB混淆
下一篇
Watchdog:python的看门狗