python面试题:web框架(三)
三、DRF(Django REST Framework)基础
-
DRF 的核心组件有哪些?(Serializers、ViewSets、Routers、Authentication、Permissions)
-
Django REST framework(简称 DRF)是用于构建 Web API 的强大且灵活的工具包。它的核心组件主要包括以下几个:
- Serializers(序列化器):
- 功能:将复杂的数据类型(如 Django 模型实例)转换为 Python 原生数据类型,以便渲染为 JSON、XML 等格式;也负责反序列化,将数据验证并保存回数据库。
- 用途:定义数据的输入和输出格式,类似于 Django 的 Form 或 ModelForm。
- 示例类:Serializer、ModelSerializer。
- ViewSets(视图集):
- 功能:将一组相关的视图逻辑组织在一起,简化代码,提高可重用性。
- 特点:通过组合不同的动作(如 list、create、retrieve、update、destroy)来处理标准的 CRUD 操作。
- 与 APIView 相比,ViewSet 更简洁抽象,常与 Router 配合使用。
- 示例类:ModelViewSet、ReadOnlyModelViewSet、GenericViewSet。
- Routers(路由器):
- 功能:自动为 ViewSet 生成 URL 配置,减少手工编写 URLconf 的工作。
- 优势:根据 ViewSet 中定义的动作自动映射 URL 模式。
- 常见路由器:DefaultRouter、SimpleRouter。
- Authentication(认证):
- 功能:识别用户身份,确定请求是由哪个用户发起的。
- 内置方式包括:TokenAuthentication、SessionAuthentication、BasicAuthentication,以及第三方如 JWT。
- 使用位置:通常在 settings.py 中全局设置或在视图/视图集中局部设置。
- Permissions(权限):
- 功能:控制用户对 API 的访问权限,决定某个用户是否有权限执行某项操作。
- 常见权限类:
- AllowAny:允许任何人访问。
- IsAuthenticated:仅认证用户可以访问。
- IsAdminUser:仅管理员用户可以访问。
- IsAuthenticatedOrReadOnly:未认证用户只读。
- 自定义权限类:继承 BasePermission。
- 可在全局、视图或视图集级别设置。
除了以上核心组件外,DRF 还有其他重要部分如:
- Request & Response 对象:增强对 HTTP 请求和响应的处理能力。
- Generic Views(通用视图):提供可复用的基于类的视图,如 ListCreateAPIView、RetrieveUpdateDestroyAPIView。
- Pagination(分页):控制返回数据的数量和格式。
- iltering(过滤)、Ordering(排序)、Throttling(限流)等高级功能。
总结:
DRF 的核心组件主要包括:
✅ Serializers
✅ ViewSets
✅ Routers
✅ Authentication
✅ Permissions
这些组件共同构成了 DRF 强大而灵活的 API 开发体验。
- Serializers(序列化器):
-
-
Serializer 的作用是什么?ModelSerializer 与 Serializer 的区别?
-
在 Django REST framework(DRF)中,Serializer(序列化器)起着至关重要的作用。下面分别说明 Serializer 的作用,以及 ModelSerializer 与 Serializer 的区别。
一、Serializer 的作用是什么?
Serializer 是 DRF 中的核心组件之一,主要作用如下:
1. 序列化(Serialization)
将复杂的数据类型(如 Django 模型实例、QuerySets 等)转换为 Python 原生数据类型(如 dict、list),进而可以轻松地渲染成 JSON、XML 等格式供前端或其他系统使用。
# 示例:将模型实例转为字典 serializer = UserSerializer(user_instance) data = serializer.data # {'id': 1, 'name': 'Alice', 'email': 'alice@example.com'}2. 反序列化(Deserialization)
接收前端传来的原始数据(如 JSON),将其转换并验证后还原为 Python 数据类型,并可进一步保存到数据库中。
# 示例:将 JSON 转为模型实例 serializer = UserSerializer(data=request.data) if serializer.is_valid(): user = serializer.save() # 创建新的模型实例3. 数据验证(Validation)
在反序列化过程中,可以对数据进行校验(字段验证、跨字段验证等),确保数据符合业务规则。
def validate_email(self, value): if not value.endswith('@example.com'): raise serializers.ValidationError("Email must be @example.com domain") return value4. 简化视图逻辑
通过封装序列化/反序列化和验证逻辑,使视图更简洁、清晰。
二、ModelSerializer 与 Serializer 的区别
对比项 Serializer ModelSerializer 定义方式 手动定义所有字段 自动根据模型生成字段 字段来源 需显式声明每个字段 使用 model 属性自动推断字段 Meta 类支持 无特殊要求 使用 class Meta 指定模型和字段 创建/更新方法 默认不实现 create() 和 update() 自动生成 create() 和 update() 方法 适用场景 非模型数据、复杂嵌套结构 与 Django 模型直接对应的 API 灵活性 高,完全控制字段和行为 快速开发,适用于标准 CRUD 示例对比
使用 Serializer(手动定义字段):
class UserSerializer(serializers.Serializer): id = serializers.IntegerField(read_only=True) name = serializers.CharField(max_length=100) email = serializers.EmailField() def create(self, validated_data): return User.objects.create(**validated_data) def update(self, instance, validated_data): instance.name = validated_data.get('name', instance.name) instance.email = validated_data.get('email', instance.email) instance.save() return instance使用 ModelSerializer(自动生成字段):
class UserSerializer(serializers.ModelSerializer): class Meta: model = User fields = ['id', 'name', 'email'] # 或使用 fields = '__all__' 包含所有字段✅ ModelSerializer 本质上继承自 Serializer,但提供了大量自动化功能,适合快速开发基于模型的 API。
三、总结
问题 回答 Serializer 的作用? 实现数据的序列化与反序列化、验证数据、简化视图逻辑。 ModelSerializer vs Serializer 区别? ModelSerializer 自动根据模型生成字段和方法,适合模型驱动的开发;Serializer 更灵活,适合非模型数据或需要精细控制的场景。 在实际开发中,如果 API 是对 Django 模型的 CRUD 操作,优先使用 ModelSerializer;若处理非模型数据或需要高度定制,则使用 Serializer。
-
-
如何在 DRF 中实现字段验证(validate_xxx 方法)?
-
在 Django REST Framework(DRF)中,字段验证是确保传入数据符合业务规则的重要环节。DRF 提供了多种方式进行字段验证,其中
validate_<field_name>方法 是一种常用且强大的机制,用于对单个字段进行自定义验证。
一、
validate_<field_name>方法的作用- 用于对单个字段进行自定义验证。
- 方法命名规则:
validate_<字段名>(例如validate_email、validate_password)。 - 当调用
serializer.is_valid()时,DRF 会自动调用这些方法。 - 验证失败应抛出
serializers.ValidationError异常。 - 验证成功应返回该字段的“清理后”的值。
二、基本用法示例
假设我们有一个
UserSerializer,需要对email字段进行域名限制验证:from rest_framework import serializers from django.core.exceptions import ValidationError class UserSerializer(serializers.Serializer): username = serializers.CharField(max_length=100) email = serializers.EmailField() def validate_email(self, value): # 检查邮箱是否以 @example.com 结尾 if not value.endswith('@example.com'): raise serializers.ValidationError("邮箱必须使用 @example.com 域名") return value # 必须返回处理后的值使用方式:
data = {'username': 'alice', 'email': 'alice@gmail.com'} serializer = UserSerializer(data=data) if serializer.is_valid(): print("验证通过:", serializer.validated_data) else: print("验证失败:", serializer.errors) # 输出: {'email': [ErrorDetail(string='邮箱必须使用 @example.com 域名', code='invalid')]}✅ 注意:必须返回
value,否则该字段在validated_data中为None。
三、结合 ModelSerializer 使用
validate_<field_name>同样适用于ModelSerializer:class UserSerializer(serializers.ModelSerializer): class Meta: model = User fields = ['username', 'email'] def validate_username(self, value): if len(value) < 3: raise serializers.ValidationError("用户名至少需要3个字符") return value
四、其他验证方法补充
除了
validate_<field_name>,DRF 还支持以下验证方式:1. 整体验证:
validate()方法用于需要多个字段联合验证的场景(如密码确认)。
def validate(self, data): if data['password'] != data['confirm_password']: raise serializers.ValidationError("两次输入的密码不一致") return data2. 字段级约束(直接在字段上设置)
email = serializers.EmailField(max_length=100, required=True) age = serializers.IntegerField(min_value=0, max_value=150)3. 自定义验证器(Validator 列表)
from rest_framework.validators import UniqueValidator username = serializers.CharField( max_length=100, validators=[UniqueValidator(queryset=User.objects.all(), message="用户名已存在")] )
五、完整示例
class RegisterSerializer(serializers.ModelSerializer): password = serializers.CharField(write_only=True) confirm_password = serializers.CharField(write_only=True) class Meta: model = User fields = ['username', 'email', 'password', 'confirm_password'] def validate_email(self, value): if not value.endswith('@mysite.com'): raise serializers.ValidationError("仅支持 @mysite.com 邮箱注册") return value def validate_username(self, value): if User.objects.filter(username=value).exists(): raise serializers.ValidationError("用户名已被占用") return value def validate(self, data): if data['password'] != data['confirm_password']: raise serializers.ValidationError({"confirm_password": "两次密码输入不一致"}) return data def create(self, validated_data): validated_data.pop('confirm_password') user = User.objects.create_user(**validated_data) return user
六、总结
验证方式 说明 使用场景 validate_<field>单字段自定义验证 邮箱格式、用户名长度等 validate()多字段联合验证 密码确认、开始时间 < 结束时间 字段参数( min_length,max_value等)简单约束 基础数据范围控制 validators列表复用验证逻辑 唯一性检查、正则匹配等 ✅ 关键点:
validate_<field_name>是 DRF 中实现字段级验证的核心方法。- 验证失败时抛出
serializers.ValidationError。 - 验证成功后务必返回字段值。
- 可与其他验证方式结合使用,构建健壮的数据校验体系。
-
-
ViewSet 和 APIView 的区别?什么时候用哪个?
-
在 Django REST framework(DRF)中,
APIView和ViewSet都是用于构建 API 视图的核心类,但它们在设计理念、使用方式和适用场景上有明显区别。下面详细对比二者的差异,并说明何时选择哪一个。
一、APIView 与 ViewSet 的核心区别
对比维度 APIView ViewSet 基类来源 继承自 View(Django 原生视图)继承自 APIView,进一步封装设计思想 面向“HTTP 方法”编程(如 get、post) 面向“资源操作”编程(如 list、create、retrieve) URL 绑定方式 手动为每个视图函数绑定 URL(如 path('users/', UserList.as_view()))通常与 Router 配合,自动生成 URL 方法定义 重写 .get()、.post()等方法重写 .list()、.create()、.retrieve()等动作方法代码复用性 较低,每个视图独立定义 高,通过继承 ModelViewSet等可复用 CRUD 逻辑适用场景 定制化强、非标准 RESTful 接口 标准 CRUD 操作、RESTful API 快速开发 灵活性 高,完全控制请求处理逻辑 稍低,但可通过 @action装饰器扩展
二、代码示例对比
1. 使用 APIView 实现用户列表和详情
# views.py from rest_framework.views import APIView from rest_framework.response import Response from .models import User from .serializers import UserSerializer class UserList(APIView): def get(self, request): users = User.objects.all() serializer = UserSerializer(users, many=True) return Response(serializer.data) def post(self, request): serializer = UserSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=201) return Response(serializer.errors, status=400) class UserDetail(APIView): def get_object(self, pk): from django.shortcuts import get_object_or_404 return get_object_or_404(User, pk=pk) def get(self, request, pk): user = self.get_object(pk) serializer = UserSerializer(user) return Response(serializer.data) def put(self, request, pk): user = self.get_object(pk) serializer = UserSerializer(user, data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data) return Response(serializer.errors, status=400) def delete(self, request, pk): user = self.get_object(pk) user.delete() return Response(status=204) # urls.py urlpatterns = [ path('users/', UserList.as_view()), path('users/<int:pk>/', UserDetail.as_view()), ]✅ 优点:完全控制每个方法的逻辑。
❌ 缺点:重复代码多,URL 配置繁琐。
2. 使用 ViewSet 实现相同功能
# views.py from rest_framework import viewsets from .models import User from .serializers import UserSerializer class UserViewSet(viewsets.ModelViewSet): queryset = User.objects.all() serializer_class = UserSerializer # urls.py from rest_framework.routers import DefaultRouter from .views import UserViewSet router = DefaultRouter() router.register(r'users', UserViewSet) urlpatterns = router.urls✅ 自动生成以下 URL:
GET /users/→ listPOST /users/→ createGET /users/{id}/→ retrievePUT /users/{id}/→ updateDELETE /users/{id}/→ destroy
三、什么时候用 APIView?什么时候用 ViewSet?
✅ 使用 APIView 的场景:
- 非 RESTful 接口:比如需要处理复杂的业务逻辑或多个数据源混合。
- 高度定制化需求:每个 HTTP 方法的处理流程完全不同,无法复用。
- 非 CRUD 操作:如文件上传、第三方 API 转发、Webhook 处理等。
- 需要精细控制请求/响应流程:如自定义认证、限流、缓存策略等。
- 一个视图只对应一个 URL 和一个方法(如仅 POST 的登录接口)。
📌 示例:实现一个支付回调接口,只处理 POST 请求,逻辑复杂且与模型无关。
class PaymentCallback(APIView): def post(self, request): # 复杂的签名验证、异步任务触发等 ...
✅ 使用 ViewSet 的场景:
- 标准的 CRUD 操作:对单个模型进行增删改查。
- 快速开发 RESTful API:希望减少样板代码。
- 希望自动生成 URL:配合 Router 实现“零配置”路由。
- 需要复用通用逻辑:如使用
ModelViewSet快速搭建完整资源接口。 - 需要扩展自定义动作:通过
@action添加额外端点(如/users/{id}/set-admin/)。
📌 示例:管理后台的用户管理模块,支持列表、详情、创建、禁用等操作。
class UserViewSet(viewsets.ModelViewSet): queryset = User.objects.all() serializer_class = UserSerializer @action(detail=True, methods=['post']) def set_admin(self, request, pk=None): user = self.get_object() user.is_staff = True user.save() return Response({'status': 'admin set'})
四、总结:如何选择?
需求 推荐方案 快速开发标准 CRUD API ✅ ViewSet(特别是 ModelViewSet)完全控制请求处理流程 ✅ APIView 需要与 Router 集成自动生成 URL ✅ ViewSet 非 RESTful、复杂业务逻辑 ✅ APIView 想减少重复代码 ✅ ViewSet 需要自定义非标准动作 ✅ ViewSet + @action
五、进阶建议
- 从 APIView 开始学习:理解 HTTP 方法和请求生命周期。
- 优先使用 ViewSet 提升效率:尤其是在构建资源型 API 时。
- 混用两者:DRF 允许在同一个项目中同时使用
APIView和ViewSet,根据实际需求选择最合适的工具。
💡 记住:ViewSet 不是替代 APIView,而是更高层次的抽象。理解底层原理后,才能灵活运用。
-
-
Router 的作用是什么?它自动生成了哪些 URL?
-
在 Django REST framework(DRF)中,Router 是一个非常重要的组件,它的主要作用是:自动为 ViewSet 生成 URL 配置,从而大幅简化 RESTful API 的路由管理,避免手动编写重复的 URL 模式。
一、Router 的作用是什么?
✅ 核心作用:
-
自动注册 URL 路由
将 ViewSet 中定义的操作(如 list、create、retrieve、update、destroy)自动映射到对应的 URL。
-
减少样板代码
无需手动为每个视图函数写
path()或url(),提升开发效率。 -
统一 URL 风格
遵循 RESTful 规范,自动生成标准化的 URL 路径(如
/api/users/,/api/users/{id}/)。 -
支持自定义动作(@action)
自动为通过
@action装饰器添加的自定义方法生成 URL。 -
与 ViewSet 深度集成
必须与 ViewSet(或其子类如 ModelViewSet)配合使用。
二、常见的 Router 类型
DRF 提供两种常用 Router:
Router 类 说明 SimpleRouter基础路由器,不包含根视图(API Root) DefaultRouter继承自 SimpleRouter,额外提供一个可浏览的 API 根页面(如 /api/)通常使用
DefaultRouter,因为它更友好(带 HTML 文档页)。
三、Router 自动生成哪些 URL?
当你使用
router.register()注册一个 ViewSet 时,DRF 会根据 ViewSet 提供的动作(actions)自动生成一组 URL。示例:注册一个
UserViewSet# views.py from rest_framework import viewsets from .models import User from .serializers import UserSerializer class UserViewSet(viewsets.ModelViewSet): queryset = User.objects.all() serializer_class = UserSerializer # urls.py from rest_framework.routers import DefaultRouter from .views import UserViewSet router = DefaultRouter() router.register(r'users', UserViewSet) # 注册路由 urlpatterns = router.urls🎯 自动生成的 URL 模式(以
users为例):HTTP 方法 URL 路径 对应 ViewSet 方法 说明 GET /users/.list()获取用户列表 POST /users/.create()创建新用户 GET /users/{id}/.retrieve()获取单个用户详情 PUT /users/{id}/.update()全量更新用户信息 PATCH /users/{id}/.partial_update()部分更新用户信息 DELETE /users/{id}/.destroy()删除用户 ✅ 这些 URL 全部由
router.register()自动生成,无需手写!
四、支持自定义动作时的 URL 生成
如果在 ViewSet 中使用
@action装饰器添加自定义方法,Router 也会自动为其生成 URL。示例:添加自定义动作
from rest_framework.decorators import action from rest_framework.response import Response class UserViewSet(viewsets.ModelViewSet): queryset = User.objects.all() serializer_class = UserSerializer @action(detail=False, methods=['get']) def recent(self, request): """获取最近注册的5个用户""" recent_users = User.objects.order_by('-date_joined')[:5] serializer = self.get_serializer(recent_users, many=True) return Response(serializer.data) @action(detail=True, methods=['post']) def set_inactive(self, request, pk=None): """将指定用户设为非活跃状态""" user = self.get_object() user.is_active = False user.save() return Response({'status': 'user deactivated'})🎯 自动新增的 URL:
HTTP 方法 URL 路径 对应方法 说明 GET /users/recent/.recent()自定义集合动作(detail=False) POST /users/{id}/set_inactive/.set_inactive()自定义详情动作(detail=True) 🔍 注意:
detail=False:动作作用于整个资源集合,URL 不带 ID。detail=True:动作作用于单个资源,URL 包含{id}。
五、DefaultRouter 还会生成一个 API Root 页面
使用
DefaultRouter时,除了资源路由外,还会自动添加一个根视图:URL 说明 /或/api/(取决于注册前缀)显示所有注册资源的链接(HTML 页面),方便调试和浏览 访问
/api/会看到类似这样的页面:Users • http://localhost:8000/api/users/ • http://localhost:8000/api/users/{id}/
六、总结
✅ Router 的作用总结:
- 自动为 ViewSet 生成 RESTful 风格的 URL。
- 支持标准 CRUD 操作和自定义动作。
- 减少手动配置 URL 的工作量。
- 提升 API 的一致性和可维护性。
🧩 自动生成的典型 URL(以
users为例):GET, POST /users/ → list(), create() GET, PUT, PATCH, DELETE /users/{id}/ → retrieve(), update(), partial_update(), destroy() GET /users/recent/ → @action(detail=False) POST /users/{id}/set_inactive/ → @action(detail=True)💡 最佳实践:
- 使用
DefaultRouter以获得更好的开发体验(含 API 根页面)。 - 始终将 ViewSet 与 Router 配合使用,除非有特殊需求。
- 利用
@action扩展非标准操作,保持 URL 整洁统一。
🚀 Router 是 DRF 实现“约定优于配置”(Convention over Configuration)哲学的关键体现!
-
-
-
Generic Views(如 ListCreateAPIView)的优势和使用场景?
-
在 Django REST framework(DRF)中,Generic Views(通用视图) 是一组预定义的基于类的视图,它们封装了常见的 API 开发模式(如列表展示、详情查看、创建、更新、删除等)。像
ListCreateAPIView、RetrieveUpdateDestroyAPIView等都是 Generic Views 的具体实现。
一、什么是 Generic Views?
Generic Views 继承自
APIView,并在此基础上结合了mixin类(如ListModelMixin、CreateModelMixin等),为常见的 RESTful 操作提供了开箱即用的实现。常见的 Generic Views:
类名 功能描述 ListAPIView仅支持列表查询(GET) CreateAPIView仅支持创建(POST) RetrieveAPIView仅支持获取详情(GET) UpdateAPIView支持更新(PUT、PATCH) DestroyAPIView支持删除(DELETE) ListCreateAPIView支持列表 + 创建(GET + POST)✅ 常用 RetrieveUpdateAPIView支持详情 + 更新(GET + PUT/PATCH) RetrieveDestroyAPIView支持详情 + 删除(GET + DELETE) RetrieveUpdateDestroyAPIView支持详情 + 更新 + 删除(GET + PUT/PATCH + DELETE)✅ 常用
二、Generic Views 的优势
1. 代码复用性强
- 封装了通用的 CRUD 逻辑,避免重复编写
get(),post()等方法。 - 开发者只需关注数据来源(
queryset)和序列化方式(serializer_class)。
2. 开发效率高
- 几行代码即可搭建完整的 API 端点。
- 无需手动实现
list(),create()等方法的细节。
3. 一致性好
- 所有基于 Generic Views 的接口行为一致,便于维护和团队协作。
4. 易于扩展
- 可通过重写方法(如
get_queryset()、perform_create())实现自定义逻辑。 - 支持添加权限、分页、过滤等功能。
5. 与 DRF 生态无缝集成
- 自动支持分页、过滤、排序、限流等高级特性(通过
filter_backends等配置)。
三、使用示例:ListCreateAPIView
场景:实现一个用户列表和创建用户的接口
# views.py from rest_framework.generics import ListCreateAPIView from .models import User from .serializers import UserSerializer class UserListCreateView(ListCreateAPIView): queryset = User.objects.all() serializer_class = UserSerializer # 可选:自定义查询集 def get_queryset(self): return User.objects.filter(is_active=True) # 可选:创建前预处理 def perform_create(self, serializer): serializer.save(created_by=self.request.user)对应 URL 配置:
# urls.py from django.urls import path from .views import UserListCreateView urlpatterns = [ path('users/', UserListCreateView.as_view(), name='user-list-create'), ]自动支持的接口:
方法 URL 功能 GET /users/获取所有用户列表(支持分页) POST /users/创建新用户 ✅ 无需手动写
get()或post()方法!
四、使用场景
✅ 适合使用 Generic Views 的场景:
-
标准的 CRUD 操作
如对单个模型进行列表、详情、创建、更新、删除。
-
快速原型开发
需要在短时间内搭建可用的 API。
-
前后端分离项目的基础接口
如管理后台的用户、文章、订单等资源接口。
-
不需要复杂自定义逻辑的视图
业务逻辑可以直接通过配置或少量重写完成。
-
希望统一视图风格
团队项目中保持代码风格一致。
❌ 不适合使用 Generic Views 的场景:
-
高度定制化的业务逻辑
如一个接口需要聚合多个模型、调用外部服务、复杂权限判断等。
-
非 RESTful 接口
如文件上传、Webhook、批量操作等不符合标准 CRUD 的模式。
-
需要完全控制请求/响应流程
此时应使用
APIView或View。 -
动态 URL 结构或非常规方法分发
如根据参数决定执行不同操作。
📌 提示:如果 Generic Views 无法满足需求,可以考虑:
- 继承 Generic Views 并重写方法;
- 改用
APIView; - 使用
ViewSet+ Router(更适合资源型 API)。
五、Generic Views vs ViewSet 对比
特性 Generic Views ViewSet 配置方式 手动绑定 URL( as_view())自动注册( router.register())适用粒度 单个 HTTP 方法组合(如 GET+POST) 整个资源操作集合 URL 灵活性 高(可自由定义路径) 标准化(RESTful) 开发速度 快 更快(尤其配合 Router) 适用场景 简单或中等复杂度的接口 标准 RESTful 资源 API 💡 建议:
- 如果只需要一两个动作(如列表+创建),用
ListCreateAPIView更直观。 - 如果需要完整的 CRUD 或自定义动作,用
ModelViewSet+ Router 更高效。
六、总结
✅ Generic Views 的优势:
- 提高开发效率,减少样板代码
- 内置分页、过滤等支持
- 易于理解和维护
- 适合快速构建标准化 API
🎯 推荐使用场景:
当你需要为一个模型快速实现标准的“列表 + 创建”或“详情 + 更新 + 删除”接口时,
ListCreateAPIView和RetrieveUpdateDestroyAPIView是最佳选择。📌 示例代码回顾:
class ArticleListCreateView(ListCreateAPIView): queryset = Article.objects.all() serializer_class = ArticleSerializer permission_classes = [IsAuthenticatedOrReadOnly] def perform_create(self, serializer): serializer.save(author=self.request.user)一行
as_view()就能上线一个功能完善的接口!🚀 善用 Generic Views,让 DRF 开发事半功倍!
- 封装了通用的 CRUD 逻辑,避免重复编写
-
-
DRF 中如何实现分页(Pagination)?有哪几种内置分页类?
-
在 Django REST framework(DRF)中,分页(Pagination) 是一种重要的机制,用于控制 API 响应中返回的数据量,避免一次性返回过多数据导致性能问题或带宽浪费。DRF 提供了灵活的分页支持,既可以在全局配置,也可以在单个视图中自定义。
一、为什么需要分页?
- 防止一次性返回大量数据(如数万条记录),导致:
- 响应缓慢
- 内存占用过高
- 前端处理困难
- 提升用户体验和 API 性能
- 支持按需加载(如无限滚动)
二、DRF 中如何实现分页?
DRF 实现分页的核心步骤:
步骤 1:配置分页类
选择一个分页类(内置或自定义),并设置相关参数。
步骤 2:启用分页
- 全局启用:在
settings.py中配置DEFAULT_PAGINATION_CLASS和PAGE_SIZE - 局部启用:在视图类中单独指定
pagination_class
步骤 3:访问分页数据
客户端通过
?page=参数请求特定页码(如?page=2)
三、DRF 的内置分页类(3 种)
DRF 提供了三种内置分页类,位于
rest_framework.pagination模块中:分页类 说明 响应格式特点 PageNumberPagination基于页码的分页(最常用) 返回当前页数据和页码信息 LimitOffsetPagination基于偏移量的分页(类似 SQL LIMIT/OFFSET) 返回起始位置和数量 CursorPagination基于游标的分页(高效、防跳页) 返回下一页游标,适合大数据量
1.
PageNumberPagination(页码分页)✅ 特点:
- 通过
?page=指定页码(如?page=3) - 可配置每页数量
?page_size=20
🔧 全局配置(settings.py):
REST_FRAMEWORK = { 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', 'PAGE_SIZE': 10 # 默认每页 10 条 }🔧 局部配置(视图中):
from rest_framework.pagination import PageNumberPagination from rest_framework.generics import ListAPIView from .models import Book from .serializers import BookSerializer class StandardResultsSetPagination(PageNumberPagination): page_size = 5 page_size_query_param = 'page_size' # 允许客户端指定每页大小 max_page_size = 100 # 限制最大每页数量 class BookListView(ListAPIView): queryset = Book.objects.all() serializer_class = BookSerializer pagination_class = StandardResultsSetPagination📦 响应示例:
{ "count": 45, "next": "http://api.example.com/books/?page=2", "previous": null, "results": [ {"id": 1, "title": "Book A"}, {"id": 2, "title": "Book B"}, ... ] }字段说明:
count: 总记录数next: 下一页 URL(若无则为null)previous: 上一页 URLresults: 当前页数据列表
2.
LimitOffsetPagination(偏移量分页)✅ 特点:
- 使用
?limit=和?offset=控制(如?limit=10&offset=20) - 类似数据库
LIMIT 10 OFFSET 20
🔧 使用示例:
from rest_framework.pagination import LimitOffsetPagination class BookListView(ListAPIView): queryset = Book.objects.all() serializer_class = BookSerializer pagination_class = LimitOffsetPagination📦 响应示例:
{ "count": 45, "next": "http://api.example.com/books/?limit=10&offset=30", "previous": "http://api.example.com/books/?limit=10&offset=10", "results": [...] }💡 适合需要“从第 N 条开始取 M 条”的场景,如搜索结果跳转。
3.
CursorPagination(游标分页)✅ 特点:
- 使用“游标”(cursor)定位下一页,不支持跳转到任意页
- 高性能,适合无限滚动、实时数据流
- 避免“跳页”导致的漏数据或重复数据(如数据在分页期间被修改)
🔧 使用示例:
from rest_framework.pagination import CursorPagination class BookCursorPagination(CursorPagination): page_size = 10 ordering = '-created_at' # 必须指定排序字段(通常是时间戳或 ID) cursor_query_param = 'cursor' page_size_query_param = 'page_size' class BookListView(ListAPIView): queryset = Book.objects.all() serializer_class = BookSerializer pagination_class = BookCursorPagination📦 响应示例:
{ "next": "http://api.example.com/books/?cursor=cD0yMDIzLTAxLTE1JmNv%3D", "previous": null, "results": [...] }⚠️ 注意:
- 必须设置
ordering,否则报错 - 不支持
page参数,只能通过next/previous链接翻页 - 无法跳转到第 5 页,只能“上一页/下一页”
四、如何禁用分页?
方法 1:全局禁用
REST_FRAMEWORK = { 'DEFAULT_PAGINATION_CLASS': None }方法 2:视图中禁用
class BookListView(ListAPIView): queryset = Book.objects.all() serializer_class = BookSerializer pagination_class = None # 禁用分页方法 3:单个请求禁用
某些 Generic Views 支持
?disable_pagination=true(需自定义),但默认不支持。通常做法是:- 提供另一个无分页的视图
- 或使用
django.core.paginator.Paginator手动控制
五、自定义分页类
你可以继承任一内置分页类,实现完全自定义:
class CustomPagination(PageNumberPagination): page_size = 8 page_query_param = 'page' # 默认就是 'page' page_size_query_param = 'size' max_page_size = 50 def get_paginated_response(self, data): return Response({ 'total': self.page.paginator.count, 'pages': self.page.paginator.num_pages, 'current_page': self.page.number, 'items': data })
六、总结
分页类 适用场景 是否支持跳页 性能 推荐指数 PageNumberPagination常规列表页(如后台管理) ✅ 支持 一般 ⭐⭐⭐⭐ LimitOffsetPagination搜索、筛选、API 灵活查询 ✅ 支持 一般 ⭐⭐⭐ CursorPagination无限滚动、实时数据、大数据量 ❌ 不支持 高 ⭐⭐⭐⭐⭐(特定场景) ✅ 最佳实践建议:
- 普通后台管理系统 → 使用
PageNumberPagination - 移动端无限滚动 → 使用
CursorPagination - 需要精确控制查询位置 → 使用
LimitOffsetPagination - 始终设置合理的
PAGE_SIZE或max_page_size防止滥用
🚀 合理使用分页,是构建高性能、可扩展 API 的关键一步!
- 防止一次性返回大量数据(如数万条记录),导致:
-
-
DRF 的认证方式有哪几种?如何实现 Token 认证和 JWT 认证?
-
在 Django REST framework(DRF)中,认证(Authentication) 是确定“谁在访问 API”的核心机制。DRF 提供了灵活的认证系统,支持多种认证方式,并允许你根据需求组合或自定义认证后端。
一、DRF 的内置认证方式
DRF 默认支持以下几种认证类(位于
rest_framework.authentication):认证类 说明 SessionAuthentication使用 Django 的 session 机制(适用于浏览器 + 登录状态) BasicAuthenticationHTTP 基础认证(用户名+密码明文传输,仅用于测试) TokenAuthentication基于 Token 的字符串认证(DRF 自带,较简单) JSONWebTokenAuthentication(第三方)基于 JWT(JSON Web Token)的现代认证方式(需安装 djangorestframework-simplejwt)✅ 你可以在全局或视图级别配置使用哪些认证方式。
二、认证的配置方式
1. 全局配置(推荐)
在
settings.py中配置:REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.BasicAuthentication', # 'rest_framework.authentication.TokenAuthentication', # 启用 Token # 'rest_framework_simplejwt.authentication.JWTAuthentication', # 启用 JWT ], }2. 局部配置(视图或视图集)
from rest_framework.authentication import TokenAuthentication from rest_framework.permissions import IsAuthenticated from rest_framework.views import APIView class ProtectedView(APIView): authentication_classes = [TokenAuthentication] permission_classes = [IsAuthenticated] def get(self, request): return Response({"message": f"Hello, {request.user.username}!"})
三、实现 Token 认证(DRF 自带)
步骤 1:启用 TokenAuthentication
# settings.py REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework.authentication.TokenAuthentication', ], 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.IsAuthenticated', # 保护所有接口 ], }步骤 2:迁移数据库(创建 token 表)
python manage.py migrateDRF 会自动创建
authtoken_token表用于存储 token。步骤 3:为用户创建 Token
方法 1:手动创建(Django shell)
python manage.py shell from django.contrib.auth.models import User from rest_framework.authtoken.models import Token user = User.objects.get(username='alice') token = Token.objects.create(user=user) print(token.key) # 输出:a1b2c3d4e5f6...方法 2:自动创建(用户注册时生成)
from django.conf import settings from rest_framework.authtoken.models import Token @receiver(post_save, sender=settings.AUTH_USER_MODEL) def create_auth_token(sender, instance=None, created=False, **kwargs): if created: Token.objects.create(user=instance)添加到
signals.py并在apps.py中注册。步骤 4:客户端使用 Token 访问 API
在请求头中添加:
Authorization: Token a1b2c3d4e5f6...或使用 curl:
curl -H "Authorization: Token a1b2c3d4e5f6..." http://localhost:8000/api/protected/
四、实现 JWT 认证(推荐用于现代应用)
JWT(JSON Web Token)是目前最流行的无状态认证方式,适合前后端分离、移动端、微服务架构。
步骤 1:安装依赖
pip install djangorestframework-simplejwt步骤 2:配置 JWT 认证
# settings.py REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework_simplejwt.authentication.JWTAuthentication', ), } # JWT 配置(可选) from datetime import timedelta SIMPLE_JWT = { 'ACCESS_TOKEN_LIFETIME': timedelta(minutes=60), # Access Token 有效期 'REFRESH_TOKEN_LIFETIME': timedelta(days=1), # Refresh Token 有效期 'ROTATE_REFRESH_TOKENS': False, 'BLACKLIST_AFTER_ROTATION': True, }步骤 3:配置 URL 路由
# urls.py from django.urls import path from rest_framework_simplejwt.views import ( TokenObtainPairView, TokenRefreshView, ) urlpatterns = [ path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'), path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), ]✅
TokenObtainPairView:登录时获取 access 和 refresh token✅
TokenRefreshView:用 refresh token 刷新 access token步骤 4:登录获取 Token
发送 POST 请求:
POST /api/token/ { "username": "alice", "password": "123456" }响应:
{ "access": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." }步骤 5:使用 Access Token 访问受保护接口
在请求头中添加:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...注意:
Bearer后面有一个空格!curl 示例:
curl -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." http://localhost:8000/api/user/步骤 6:(可选)启用 Token 黑名单(推荐)
pip install djangorestframework-simplejwt[token_blacklist] # settings.py INSTALLED_APPS += ['rest_framework_simplejwt.token_blacklist'] # 运行迁移 python manage.py migrate然后配置:
SIMPLE_JWT = { 'ROTATE_REFRESH_TOKENS': True, 'BLACKLIST_AFTER_ROTATION': True, }添加登出接口(撤销 refresh token):
# urls.py from rest_framework_simplejwt.views import TokenBlacklistView urlpatterns += [ path('api/token/blacklist/', TokenBlacklistView.as_view(), name='token_blacklist'), ]
五、Token 认证 vs JWT 认证对比
特性 Token Authentication JWT Authentication 存储位置 服务端数据库( authtoken_token表)客户端(本地存储或内存) 状态性 有状态(服务端跟踪 token) 无状态(服务端不存 token) 扩展性 差(难扩展 payload) 好(可自定义 claims) 安全性 一般(固定字符串) 高(可加密、过期、签名) 移动端支持 一般 优秀 注销/踢人 需手动删 token 需配合黑名单(如 Redis) 推荐场景 内部系统、简单项目 前后端分离、APP、微服务 ✅ 推荐:新项目优先使用 JWT(如 SimpleJWT)
六、总结
✅ DRF 支持的主要认证方式:
SessionAuthentication– 浏览器会话(传统 Web)BasicAuthentication– 测试用(不安全)TokenAuthentication– DRF 自带,简单但有状态JWTAuthentication(viadjangorestframework-simplejwt)– 现代首选,无状态、安全、灵活
🛠️ 实现要点:
认证方式 关键步骤 Token 启用类 → 迁移 → 创建 token → Authorization: Token xxxJWT 安装 SimpleJWT → 配置 → 路由 → 登录获取 token → Authorization: Bearer xxx💡 最佳实践:
- 生产环境避免使用
BasicAuthentication - 前后端分离项目推荐使用 JWT + HTTPS
- 敏感操作建议结合权限(
IsAuthenticated、IsAdminUser等) - 定期轮换密钥,设置合理的 token 有效期
🚀 选择合适的认证方式,是保障 API 安全和用户体验的关键!
-
-
权限类(Permission Classes)有哪些内置类型?如何自定义权限?
-
在 Django REST framework(DRF)中,权限类(Permission Classes) 用于控制用户是否有权限访问某个 API 视图或执行某个操作。它是保障 API 安全性的核心机制之一。
一、DRF 内置权限类(Built-in Permission Classes)
DRF 提供了多个内置权限类,位于
rest_framework.permissions模块中:权限类 说明 AllowAny允许任何用户访问(包括匿名用户) IsAuthenticated仅允许已认证的用户访问 IsAdminUser仅允许 is_staff=True的管理员用户访问IsAuthenticatedOrReadOnly已认证用户可读写,匿名用户只读(GET/HEAD/OPTIONS) DjangoModelPermissions基于 Django 模型的权限系统(需配合 Django 的 auth 权限) DjangoModelPermissionsOrAnonReadOnly类似 DjangoModelPermissions,但允许匿名用户只读DjangoObjectPermissions支持对象级别的权限控制(需配合 django-guardian等)
1.
AllowAny-
用途:公开接口,如首页、登录、文档等。
-
示例:
from rest_framework.permissions import AllowAny class PublicView(APIView): permission_classes = [AllowAny]
2.
IsAuthenticated-
用途:需要登录才能访问,如用户中心、个人资料。
-
示例:
from rest_framework.permissions import IsAuthenticated class ProfileView(APIView): permission_classes = [IsAuthenticated]
3.
IsAdminUser-
用途:仅管理员可访问,如后台管理接口。
-
示例:
from rest_framework.permissions import IsAdminUser class AdminOnlyView(APIView): permission_classes = [IsAdminUser]
4.
IsAuthenticatedOrReadOnly-
用途:登录用户可读写,游客只能查看。
-
常用于:博客、商品列表等开放但需保护的场景。
-
示例:
from rest_framework.permissions import IsAuthenticatedOrReadOnly class ArticleListView(ListCreateAPIView): permission_classes = [IsAuthenticatedOrReadOnly]
5.
DjangoModelPermissions-
用途:基于 Django 的
add/change/delete/view权限。 -
要求:必须在模型中设置权限(默认已开启)。
-
示例:
from rest_framework.permissions import DjangoModelPermissions class ArticleViewSet(ModelViewSet): queryset = Article.objects.all() serializer_class = ArticleSerializer permission_classes = [DjangoModelPermissions] # 需有对应权限才能 POST/PUT/DELETE用户必须拥有
app.add_article、app.change_article等权限才能操作。
6.
DjangoObjectPermissions- 用途:细粒度对象级权限(如“只能编辑自己发布的文章”)。
- 依赖:需安装
django-guardian并实现ObjectPermissionBackend。 - 使用较少,适合复杂权限系统。
二、权限的配置方式
1. 全局配置(settings.py)
REST_FRAMEWORK = { 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.IsAuthenticated', # 默认所有接口需登录 ] }2. 局部配置(视图或视图集)
from rest_framework.permissions import IsAdminUser class UserManagementView(APIView): permission_classes = [IsAdminUser] # 覆盖全局设置3. 动态设置(在方法中)
def get_permissions(self): if self.action == 'create': return [IsAdminUser()] elif self.action == 'list': return [AllowAny()] return [IsAuthenticated()]适用于
ViewSet,可根据动作动态调整权限。
三、如何自定义权限类?
当内置权限无法满足需求时(如“VIP 用户才能访问”、“作者本人才能编辑”),可以自定义权限类。
✅ 自定义权限类的要求:
继承
BasePermission实现
has_permission()(控制是否允许访问视图)或实现
has_object_permission()(控制是否允许操作某个对象)
示例 1:只允许 VIP 用户访问
# permissions.py from rest_framework import permissions class IsVIPUser(permissions.BasePermission): """ 仅允许 is_vip=True 的用户访问 """ def has_permission(self, request, view): return request.user and request.user.is_authenticated and getattr(request.user, 'is_vip', False)使用:
from .permissions import IsVIPUser class PremiumContentView(APIView): permission_classes = [IsVIPUser]
示例 2:只有作者本人才能编辑文章(对象级权限)
# permissions.py class IsAuthorOrReadOnly(permissions.BasePermission): """ 作者可读写,其他人只读 """ def has_object_permission(self, request, view, obj): # 读取权限允许所有用户 if request.method in permissions.SAFE_METHODS: # GET, HEAD, OPTIONS return True # 写入权限只允许作者 return obj.author == request.user使用(在
RetrieveUpdateDestroyAPIView或ModelViewSet中):class ArticleDetailView(generics.RetrieveUpdateDestroyAPIView): queryset = Article.objects.all() serializer_class = ArticleSerializer permission_classes = [IsAuthorOrReadOnly]⚠️
has_object_permission只在视图返回单个对象时调用(如retrieve,update,destroy),不会在list中调用。
示例 3:组合多个权限(AND 逻辑)
DRF 会自动组合多个权限类(相当于“与”关系):
permission_classes = [IsAuthenticated, IsVIPUser] # 必须同时满足等价于:
class ComposedPermission(permissions.BasePermission): def has_permission(self, request, view): return ( permissions.IsAuthenticated().has_permission(request, view) and IsVIPUser().has_permission(request, view) )
四、权限类方法详解
方法 调用时机 返回值 说明 has_permission(request, view)每次请求进入视图时调用 True/False控制是否允许访问该视图 has_object_permission(request, view, obj)视图返回单个对象时调用(如 get_object())True/False控制是否允许操作该对象 ✅ 如果
has_permission返回False,直接返回 403,不会调用has_object_permission。
五、总结
✅ 内置权限类速查:
权限类 适用场景 AllowAny公开接口 IsAuthenticated需登录 IsAdminUser仅管理员 IsAuthenticatedOrReadOnly登录读写,游客只读 DjangoModelPermissions基于模型权限 DjangoObjectPermissions对象级权限(需扩展) 🛠️ 自定义权限步骤:
- 继承
permissions.BasePermission - 实现
has_permission()或has_object_permission() - 返回
True(允许)或False(拒绝) - 在视图中引用自定义类
💡 最佳实践:
- 遵循“最小权限原则”:默认禁止,按需开放
- 敏感操作(如删除、支付)应叠加多重验证(权限 + 业务逻辑)
- 使用
SAFE_METHODS区分读写操作 - 复杂权限建议封装为独立类,便于复用和测试
🚀 合理设计权限系统,是保障 API 安全性和用户体验的基石!
-
-
-
节流(Throttling)的作用是什么?举例说明限制某 IP 访问频率的方法。
-
在 Django REST framework(DRF)中,节流(Throttling) 是一种流量控制机制,用于限制用户或客户端在特定时间内的请求次数,防止 API 被滥用、恶意攻击(如暴力破解、爬虫、DDoS)或意外过载。
一、节流(Throttling)的作用
✅ 核心作用:
- 防止滥用:避免单个用户/IP 高频调用接口(如短信发送、登录尝试)。
- 保护服务器资源:防止因突发流量导致服务崩溃。
- 提升系统稳定性:平滑请求负载,避免峰值冲击。
- 实现公平使用:防止少数用户占用过多资源。
- 安全防护:抵御暴力破解、刷单、爬虫等行为。
📌 类比:就像高速公路的“限速”或景区的“人流管控”。
二、DRF 中的节流机制
DRF 提供了灵活的节流系统,支持:
- 按用户、IP、自定义标识限流
- 不同视图设置不同限流策略
- 全局或局部配置
- 自定义节流类
内置节流类(
rest_framework.throttling):节流类 说明 AnonRateThrottle限制匿名用户(按 IP) UserRateThrottle限制已认证用户(按用户 ID) ScopedRateThrottle按自定义作用域(scope)限流,支持不同接口不同策略 SimpleRateThrottle所有节流类的基类,可自定义逻辑
三、举例:限制某 IP 的访问频率
场景:限制匿名用户(按 IP)每分钟最多访问 5 次
/api/login/步骤 1:全局启用节流(可选)
# settings.py REST_FRAMEWORK = { 'DEFAULT_THROTTLE_CLASSES': [ 'rest_framework.throttling.AnonRateThrottle', # 匿名用户按 IP 限流 'rest_framework.throttling.UserRateThrottle' # 登录用户按用户限流 ], 'DEFAULT_THROTTLE_RATES': { 'anon': '5/min', # 匿名用户:每分钟 5 次 'user': '100/day' # 登录用户:每天 100 次 } }✅
'5/min'表示每分钟最多 5 次请求。
支持单位:/sec(秒)、/min(分)、/hour(小时)、/day(天)
步骤 2:在视图中单独设置节流(推荐用于精细控制)
如果不想全局生效,可以在特定视图中设置:
# views.py from rest_framework.throttling import AnonRateThrottle from rest_framework.views import APIView from rest_framework.response import Response class LoginView(APIView): throttle_classes = [AnonRateThrottle] # 只对这个视图启用 IP 限流 def post(self, request): # 登录逻辑 return Response({"message": "Login successful"})⚠️ 注意:要使
AnonRateThrottle生效,需在settings.py中配置DEFAULT_THROTTLE_RATES包含'anon'。
步骤 3:自定义节流类(更灵活的控制)
如果你想针对
/api/login/设置更严格的限制(如每分钟 3 次),可以自定义节流类:# throttles.py from rest_framework.throttling import AnonRateThrottle class LoginAttemptThrottle(AnonRateThrottle): scope = 'login_attempts' # 自定义作用域名称# settings.py REST_FRAMEWORK = { 'DEFAULT_THROTTLE_RATES': { 'anon': '5/min', 'user': '100/day', 'login_attempts': '3/min', # 为 login_attempts 设置独立速率 } }# views.py from .throttles import LoginAttemptThrottle class LoginView(APIView): throttle_classes = [LoginAttemptThrottle] # 使用自定义节流 def post(self, request): # 登录逻辑 return Response({"message": "Login attempt recorded"})
四、测试节流效果
使用
curl模拟多次请求:# 连续发送 6 次请求(超过 5 次/分钟) for i in {1..6}; do curl -X POST http://localhost:8000/api/login/ \ -H "Content-Type: application/json" \ -d '{"username":"test","password":"123"}' done第 6 次请求将返回:
{ "detail": "Request was throttled. Expected available in 59 seconds." }状态码:
429 Too Many Requests
五、查看剩余请求次数(可选)
DRF 会在响应头中返回节流信息(如果配置了
THROTTLE_RATES):X-Throttle-Wait-Seconds: 59 Retry-After: 59你也可以通过
@property自定义响应提示。
六、其他实用技巧
1. 只对特定方法限流
class LoginView(APIView): throttle_classes = [LoginAttemptThrottle] def post(self, request): ... def get(self, request): return Response({"info": "This is a public endpoint"}) # 不受限流影响?⚠️ 默认整个视图都受限流。若只想对
POST限流,需自定义逻辑或使用@action拆分视图。2. 白名单用户(如管理员不限流)
class CustomAnonThrottle(AnonRateThrottle): def allow_request(self, request, view): # 管理员 IP 或特定条件不限流 if request.META.get('REMOTE_ADDR') in ['127.0.0.1', '192.168.1.100']: return True return super().allow_request(request, view)
七、总结
✅ 节流的作用:
- 防止 API 被滥用或攻击
- 控制资源使用,提升稳定性
- 实现公平访问策略
🎯 限制 IP 访问频率的方法:
方法 说明 使用 AnonRateThrottle按 IP 限制匿名用户 配置 DEFAULT_THROTTLE_RATES设置 'anon': '5/min'等规则局部设置 throttle_classes精确控制某个视图 自定义节流类 实现更细粒度的策略(如登录接口单独限流) 💡 最佳实践:
- 登录、注册、发送验证码等敏感接口应严格限流(如 3~5 次/分钟)
- 结合日志监控异常请求模式
- 对 VIP 用户可提高限额或不限流
- 使用
ScopedRateThrottle实现多接口差异化策略
🚀 合理使用节流,是构建安全、稳定、高可用 API 的重要保障!
-

浙公网安备 33010602011771号