DRF框架
约 4791 字大约 16 分钟
2025-10-02
介绍
Django REST framework (DRF) 是一个功能强大且灵活的工具包,用于在 Django 中构建 Web API。
你可以把它理解为 Django 的一个“超级英雄”扩展。Django 本身最擅长的是构建具有前端模板的“全栈”网站(即后端+前端页面)。而 DRF 的职责是专门让 Django 专注于扮演强大、安全的“后端 API 服务器”角色,为各种客户端(如 Web 前端、移动App、其他服务等)提供数据接口。
它的核心作用是:将你的 Django 数据模型(Models)快速、轻松、标准化地转换为 RESTful 风格的 API 接口。
主要特点和核心功能
DRF 之所以如此流行,是因为它封装了构建 API 的许多通用、繁琐且容易出错的部分,提供了“开箱即用”的解决方案:
序列化与反序列化
这是 DRF 最核心的功能,也是 API 数据交互的基础。
序列化:将 Django 的模型(Model)实例或复杂的查询集(QuerySet)转换为易于传输的数据格式,如 JSON 或 XML。这通常在读取数据(GET请求)时使用。
反序列化:将客户端发送的 JSON 等数据格式验证并解析成 Python 数据类型,进而可以创建或更新模型实例。这通常在创建(POST)、更新(PUT/PATCH)数据时使用。
类视图和视图集
APIView: 基于类的视图,提供了比 Django 原生 View 更适用于 API 的请求/响应循环。GenericAPIView和Mixin类:提供了与常见操作(如列表、创建、检索、更新、删除)绑定的通用行为,让你写极少的代码就能完成 CRUD 接口。ViewSet和ModelViewSet:最高级别的封装,一个ModelViewSet类可以自动为你提供一个模型的所有 CRUD 端点(List, Create, Retrieve, Update, Delete, Partial Update)。
路由系统
DRF 的 Router 类可以自动将 ViewSet 映射到 URL 配置上。你只需要注册一个 ViewSet,路由器就会自动生成标准的 RESTful URL,例如:
/api/books/-> 对应列表(GET)和创建(POST)/api/books/1/-> 对应详情(GET)、更新(PUT)、删除(DELETE)
这避免了手动编写大量重复的 URL 模式。
认证 (Authentication) 与权限 (Permissions)
API 的安全性至关重要,DRF 提供了开箱即用的、可插拔的认证和权限系统。
认证:确定用户的身份。DRF 支持多种认证方案:
SessionAuthentication(基于 Django 的会话,适合前后端未完全分离的场景)TokenAuthentication(使用令牌,最常见的方式之一)JWTAuthentication(使用 JSON Web Token,更现代和安全的方式)以及
OAuth等。权限:确定已认证的用户有权执行什么操作。
IsAuthenticated(是否已登录)IsAdminUser(是否是管理员)IsAuthenticatedOrReadOnly(未登录用户只读)DjangoModelPermissions(基于 Django 的模型权限)还可以轻松地自定义权限类。
强大的请求和响应对象
DRF 扩展了 Django 的 HttpRequest 和 HttpResponse。
Request 对象:对原生请求进行了包装,其 request.data 属性可以自动解析 JSON 或其他格式的请求体,比 Django 原生的 request.POST 更通用。
Response 对象:它是一个未渲染的模板响应,会根据客户端请求的内容类型(如 JSON)自动将数据渲染为合适的格式。
Browsable API
这是一个非常受欢迎的开发者友好功能。当你启动开发服务器并访问 DRF 生成的 API 端点时,它会呈现一个美观、可交互的 Web 界面。你可以直接在这个界面上查看 API 结构、进行 GET、POST、PUT 等操作,极大地方便了 API 的测试和调试。
可定制性
尽管 DRF 提供了高度封装的组件,但它也极其灵活。几乎所有默认行为都可以通过重写方法、自定义类(如自定义序列化器、权限类、分页类、过滤器等)来进行覆盖和扩展。
序列化与反序列化
这是 DRF 最核心的功能,也是 API 数据交互的基础。
序列化:将 Django 的模型(Model)实例或复杂的查询集(QuerySet)转换为 JSON 或 XML。这通常在读取数据(GET请求)时使用。
反序列化:将客户端发送的 JSON 等数据格式验证并解析成 Python 数据类型,进而可以创建或更新模型实例。这通常在创建(POST)、更新(PUT/PATCH)数据时使用。
DRF序列化 DRF序列化器提供了一种可以在视图中直接进行序列化的方式:
# serializers.py class GoodsSerializer(serializers.ModelSerializer): # 这里写的字段是想要进行自定义处理的字段 p_price = serializers.SerializerMethodField() # 自定义序列化方法时,方法名必须是 get_<字段名> def get_p_price(self, obj): return float(obj.p_price) # create update方法会在serializer.save()时自动调用 def create(self, validated_data): """ Create a new "article" instance """ def update(self, validated_data): """ Create a new "article" instance """ return Goods.objects.create(**validated_data) class Meta: model = Goods fields = '__all__'# views.py class GoodsMainMenu(View): def get(self, request): # 获取MainMenu表中的所有行 main_menu = MainMenu.objects.all() # 反序列化: data serializer = GoodsSerializer(data=main_menu, many=True) # 序列化: instance result = GoodsSerializer(instance=main_menu, many=True) return HttpResponse(result)
类视图和视图集
APIView
APIView 继承自 Django 的 View 类。但是 APIView 做了以下增强:
- 请求对象: 通过重写 View 的
dispatch()将Django的HttpRequest对象封装为DRF的Request对象 - 响应对象: 使用 DRF 的
Response对象,可以将响应轻松渲染成 JSON 等类型。 - 异常处理: 提供了专门的异常处理,将Django和Python异常自动转换为合适的HTTP响应
- 认证与权限: 内置了认证、权限、限流等API相关功能的钩子
APIView源码分析:
# DRF APIView 的 dispatch 方法简化逻辑
class APIView(View):
def dispatch(self, request, *args, **kwargs):
# ...
# 关键扩展 1: 将 Django 的 HttpRequest 对象转换为 DRF 的 Request 对象
# DRF 的 'request' 添加了解析器、认证器、渲染器等 DRF 特有功能,
# 提供更强大的 API(如 .data、.user、.auth 等属性)
request = self.initialize_request(request, *args, **kwargs)
# ...
try:
# 关键扩展 2:传入DRF request, 执行请求处理前的各种初始化操作
self.initial(request, *args, **kwargs)
"""
内部执行(按顺序):
1.身份认证 (Authentication):确定请求用户身份
2.权限检查 (Permission):检查用户是否有权限执行该操作
3.流量限制 (Throttling):检查请求频率是否超过限制
4.内容协商 (Content Negotiation):确定合适的渲染器
"""
# 根据 HTTP 方法(GET、POST、PUT 等)分派到对应的处理方法。
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(),
self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
# 实际执行对应的 HTTP 方法处理函数(如 get(), post() 等)。
response = handler(request, *args, **kwargs)
# 关键扩展 3:统一异常处理,捕获所有在处理过程中抛出的异常
# 将 Django 异常或 Python 内置异常转换为格式化的 API 响应
# 支持不同类型的异常对应不同的 HTTP 状态码和错误信息格式
except Exception as exc:
response = self.handle_exception(exc)
# 关键扩展 4:形成DRF response
# 确保所有响应都有正确的 Content-Length 头
# 基于客户端请求的 Accept 头选择合适的渲染器(JSON、XML、HTML等),并添加正确的 Content-Type 头
# 添加必要的响应头,如:Content-Type: application/json, text/html 等
self.response = self.finalize_response(request, response, *args, **kwargs)
return self.responseGenericAPIView
GenericAPIView继承自APIView, 它在APIView基础上进一步抽象了通用模式。它通常不直接使用, 而是与 Mixin 类(如 ListModelMixin, CreateModelMixin)结合使用,快速实现标准的 CRUD(增删改查)操作。相较于APIView它的增强如下:
模型和查询集相关属性
# 基础模型配置 queryset = None serializer_class = None # 查询集过滤和筛选 filter_backends = api_settings.DEFAULT_FILTER_BACKENDS filterset_class = None filterset_fields = None paginator = None # 查询集查找字段 lookup_field = 'pk' lookup_url_kwarg = None核心方法扩展
get_queryset():获取查询集get_object():获取单个对象get_serializer():获取序列化器filter_queryset:查询集过滤器paginate_queryset():查询集分页get_paginated_response():生成分页响应
示例:
# views.py
class UserDetailView(GenericAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
lookup_field = 'username'
def get(self, request, username):
user = self.get_object() # 使用扩展的get_object方法
serializer = self.get_serializer(user) # 使用扩展的get_serializer
return Response(serializer.data)
def put(self, request, username):
user = self.get_object()
serializer = self.get_serializer(user, data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data)ListModelMixin - 列表查询
功能:提供列表查询功能(GET 方法查询多个对象)
源码:
class ListModelMixin: def list(self, request, *args, **kwargs): queryset = self.filter_queryset(self.get_queryset()) page = self.paginate_queryset(queryset) if page is not None: serializer = self.get_serializer(page, many=True) return self.get_paginated_response(serializer.data) serializer = self.get_serializer(queryset, many=True) return Response(serializer.data)示例:
from rest_framework import mixins, generics class UserListView(mixins.ListModelMixin, generics.GenericAPIView): queryset = User.objects.all() serializer_class = UserSerializer def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs)
RetrieveModelMixin - 详情查询
功能:提供单个对象查询功能(GET 方法查询单个对象)
源码:
class RetrieveModelMixin: def retrieve(self, request, *args, **kwargs): instance = self.get_object() serializer = self.get_serializer(instance) return Response(serializer.data)示例:
class UserDetailView(mixins.RetrieveModelMixin, generics.GenericAPIView): queryset = User.objects.all() serializer_class = UserSerializer def get(self, request, *args, **kwargs): return self.retrieve(request, *args, **kwargs)
CreateModelMixin - 创建对象
功能:提供创建新对象功能(POST 方法)
源码:
class CreateModelMixin: def create(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) self.perform_create(serializer) headers = self.get_success_headers(serializer.data) return Response(serializer.data, status=201, headers=headers)示例:
class UserCreateView(mixins.CreateModelMixin, generics.GenericAPIView): queryset = User.objects.all() serializer_class = UserSerializer def post(self, request, *args, **kwargs): return self.create(request, *args, **kwargs)
UpdateModelMixin - 更新对象
功能:提供更新对象功能(PUT/PATCH 方法)
源码:
class UpdateModelMixin: def update(self, request, *args, **kwargs): partial = kwargs.pop('partial', False) instance = self.get_object() serializer = self.get_serializer(instance, data=request.data, partial=partial) serializer.is_valid(raise_exception=True) self.perform_update(serializer) return Response(serializer.data)示例:
class UserUpdateView(mixins.UpdateModelMixin, generics.GenericAPIView): queryset = User.objects.all() serializer_class = UserSerializer def put(self, request, *args, **kwargs): return self.update(request, *args, **kwargs) def patch(self, request, *args, **kwargs): return self.update(request, *args, **kwargs, partial=True)
DestroyModelMixin - 删除对象
功能:提供删除对象功能(DELETE 方法)
源码:
class DestroyModelMixin: def destroy(self, request, *args, **kwargs): instance = self.get_object() self.perform_destroy(instance) return Response(status=204)示例:
class UserDeleteView(mixins.DestroyModelMixin, generics.GenericAPIView): queryset = User.objects.all() serializer_class = UserSerializer def delete(self, request, *args, **kwargs): return self.destroy(request, *args, **kwargs)
完整的 CRUD 视图
class UserViewSet(mixins.ListModelMixin,
mixins.RetrieveModelMixin,
mixins.CreateModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
generics.GenericAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
def get(self, request, *args, **kwargs):
if 'pk' in kwargs:
return self.retrieve(request, *args, **kwargs)
return self.list(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
def put(self, request, *args, **kwargs):
return self.update(request, *args, **kwargs)
def delete(self, request, *args, **kwargs):
return self.destroy(request, *args, **kwargs)视图集 ViewSetMixin
视图集是一种将多个相关视图的逻辑组合到一个类中的高级抽象。它允许开发者用更少的代码实现完整的 CRUD(Create, Retrieve, Update, Delete)操作。
特点
减少重复代码:将 list、create、retrieve、update、delete 等操作整合到一个类中
自动化路由:配合路由器(Router)自动生成 URL 配置
保持一致性:确保同一资源的不同操作使用相同的查询集和序列化器配置
提高开发效率:用极少的代码快速构建完整的 RESTful API
核心视图集类
ViewSet:基础视图集类,可定制自己的视图逻辑GenericViewSet:最常用的基类,提供模型操作工具ModelViewSet:提供完整 CRUD 操作的"全能"视图集ReadOnlyModelViewSet:提供只读操作的视图集
ViewSet
这是最基础的 ViewSet 类,它本身不提供任何默认的 action(如 list, create)。你需要自己定义所有方法。它通常用于实现非常定制化的逻辑。
from rest_framework import viewsets, status
from rest_framework.decorators import action
from rest_framework.response import Response
from .models import Book
from .serializers import BookSerializer
class BasicBookViewSet(viewsets.ViewSet):
"""
一个基础的 ViewSet,用于演示手动实现各个动作。
"""
# GET /api/books/
def list(self, request):
queryset = Book.objects.all()
serializer = BookSerializer(queryset, many=True)
return Response(serializer.data)
# POST /api/books/
def create(self, request):
serializer = BookSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# GET /api/books/1/
def retrieve(self, request, pk=None):
try:
book = Book.objects.get(pk=pk)
except Book.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
serializer = BookSerializer(book)
return Response(serializer.data)
# PUT /api/books/1/
def update(self, request, pk=None):
try:
book = Book.objects.get(pk=pk)
except Book.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
serializer = BookSerializer(book, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# PATCH /api/books/1/
def partial_update(self, request, pk=None):
try:
book = Book.objects.get(pk=pk)
except Book.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
serializer = BookSerializer(book, data=request.data, partial=True)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# DELETE /api/books/1/
def destroy(self, request, pk=None):
try:
book = Book.objects.get(pk=pk)
except Book.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
book.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
# 自定义 Action: GET /api/books/1/latest/
# detail=True 表示这是针对单个对象的操作
@action(detail=True, methods=['get'])
def latest(self, request, pk=None):
# 这个例子可能不太符合‘latest’,但展示了如何访问单个对象
book = self.get_object() # 需要配合 mixin 或自己实现 get_object
# 假设我们返回这个对象的创建时间信息
return Response({'id': book.id, 'title': book.title})
# 自定义 Action: GET /api/books/published_after/?year=2020
# detail=False 表示这是针对整个集合的操作
@action(detail=False)
def published_after(self, request):
year = request.query_params.get('year', 2000)
books = Book.objects.filter(published_date__year__gt=year)
serializer = self.get_serializer(books, many=True)
return Response(serializer.data)GenericViewSet
GenericViewSet 继承了 ViewSet,同时也继承了 DRF 的通用视图(GenericAPIView)的行为,比如 get_queryset(), get_serializer() 等方法。它本身仍然不提供默认的 action,但为你提供了构建 action 的通用工具。你通常会结合 mixins 来使用它。
from rest_framework import viewsets, mixins
# 通过混合 Mixin 来快速构建 ViewSet
class GenericBookViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
viewsets.GenericViewSet):
"""
一个使用 GenericViewSet 和 Mixin 的示例。
这个 ViewSet 将自动提供 `list`, `create`, `retrieve`, `update`, `partial_update` 和 `destroy` 动作。
注意:我们混入了哪些 Mixin,就拥有哪些动作。
"""
queryset = Book.objects.all()
serializer_class = BookSerializer
# 例如,如果我们不想提供 list 功能,只需去掉 ListModelMixin 即可。ModelViewSet
这是最强大、最常用的 ViewSet。它继承了 GenericViewSet,并一次性包含了所有标准的 mixin 类。如果你需要对一个模型进行完整的 CRUD(增删改查),这是最佳选择。
from rest_framework import viewsets
from .models import Book
from .serializers import BookSerializer
class BookViewSet(viewsets.ModelViewSet):
"""
一个完整的 ModelViewSet 示例。
自动提供所有标准动作: list, create, retrieve, update, partial_update, destroy。
"""
queryset = Book.objects.all().order_by('-published_date') # 可以在这里定义默认排序
serializer_class = BookSerializer
# 你还可以轻松地添加权限、过滤、分页等
# permission_classes = [IsAuthenticated]
# filter_backends = [DjangoFilterBackend]
# filterset_fields = ['author', 'published_date']ReadOnlyModelViewSet
顾名思义,这个 ViewSet 只提供只读操作。它继承自 GenericViewSet,但只包含 RetrieveModelMixin 和 ListModelMixin。适用于你希望数据对外是只读的场景。
from rest_framework import viewsets
from .models import Book
from .serializers import BookSerializer
class ReadOnlyBookViewSet(viewsets.ReadOnlyModelViewSet):
"""
一个只读的 ViewSet。
自动提供 list 和 retrieve 动作。
"""
queryset = Book.objects.all()
serializer_class = BookSerializer认证与权限
核心概念
首先,必须理解认证和权限是两个不同但紧密相关的概念。
认证 - 识别“你是谁”
认证的目的是回答一个问题:“这个请求是谁发出的?” 系统需要确认用户的身份。
机制:当请求到达 DRF 视图时,认证类会检查请求中的凭据(如 session cookie、token 等)。
结果:如果认证成功,DRF 会将认证后的用户对象赋值给 request.user;如果失败,request.user 会被设置为 AnonymousUser 的实例;如果没有任何凭据,则会触发 WWW-Authenticate 头,导致 HTTP 401 Unauthorized 响应。
DRF 内置的常见认证方式:
SessionAuthentication: 使用 Django 的会话后端进行认证。适用于前后端不分离或紧密耦合的场景(如 Django 模板渲染)。TokenAuthentication: 简单的基于 Token 的认证。服务器生成一个随机字符串 Token 与用户关联,客户端在请求头中携带此 Token。BasicAuthentication: 使用 HTTP Basic Auth,将用户名和密码进行 Base64 编码后传输。仅建议在 HTTPS 下使用。
权限 - 决定“你能做什么”
权限的目的是在认证之后,回答另一个问题:“这个被认证的用户是否有权限执行这个操作?”
机制:在所有认证器运行完毕后,权限类会检查 request.user 和 request.auth(认证的附加信息,如 token),根据预定义的规则决定是否允许请求继续。
结果:如果任何权限检查失败,DRF 将返回 HTTP 403 Forbidden 响应。
DRF 内置的常见权限类:
AllowAny: 允许所有请求,无论是否认证。这是默认设置。IsAuthenticated: 只允许已认证的用户访问。IsAdminUser: 只允许user.is_staff为True的用户(管理员)访问。IsAuthenticatedOrReadOnly: 已认证用户可以执行任何操作,未认证用户只能执行安全操作(如 GET、HEAD、OPTIONS)。DjangoModelPermissions: 根据 Django 的标准模型权限(add_模型, change_模型, delete_模型)进行控制。
JWT Token 认证
安装依赖
pip install djangorestframework-simplejwt项目配置
在settings.py中配置:
INSTALLED_APPS = [
...,
'rest_framework',
'rest_framework_simplejwt'
]
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
# 配置 DRF 使用 JWT 认证
'rest_framework_simplejwt.authentication.JWTAuthentication',
)
}
# JWT 配置
from datetime import timedelta
SIMPLE_JWT = {
# token 有效期
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=60),
'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
# 允许刷新 token
'ROTATE_REFRESH_TOKENS': False, # 是否在刷新时返回新的 Refresh Token
'BLACKLIST_AFTER_ROTATION': False, # 是否将旧的 Refresh Token 加入黑名单
# 加密算法
'ALGORITHM': 'HS256',
'SIGNING_KEY': SECRET_KEY, # 使用 Django 的 SECRET_KEY
# 认证头类型
'AUTH_HEADER_TYPES': ('Bearer',),
'AUTH_HEADER_NAME': 'HTTP_AUTHORIZATION',
# token 类型声明
'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
}路由配置
在项目根 url.py 或者某个app的 urls.py 中配置:
from django.urls import path
from rest_framework_simplejwt.views import (
TokenObtainPairView,
TokenRefreshView,
TokenVerifyView,
)
urlpatterns = [
# ...
path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'), # 获取令牌(登录)
path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), # 使用refresh token刷新access token
path('api/token/verify/', TokenVerifyView.as_view(), name='token_verify'), # 验证access token是否有效
# ...
]JWT 的核心端点:Access Token 和 Refresh Token
simplejwt 采用了双 token 机制,这是业界最佳实践,旨在平衡安全性和用户体验。
Access Token:用途:用于访问受保护的 API 端点。生命周期较短(如 5-60 分钟)。
获取端点:POST /api/token/,提供 username 和 password,返回 access 和 refresh token。
使用方式:在请求头中
Authorization: Bearer <access_token>。
Refresh Token:用途:当
Access Token过期后,用于获取一对新的Access Token和Refresh Token。生命周期较长(如数天或数周)。获取新 Token 的端点:POST
/api/token/refresh/,提供过期的refresh token,返回新的access token(有时也会返回新的 refresh token,取决于配置)。重要性:用户无需重新登录,体验更好。同时,服务器可以通过使
Refresh Token失效来强制用户重新登录,增强了安全性。
一个典型的前端交互流程:
用户登录
用户提交用户名和密码,前端 POST 到
/api/token/。将返回的access_token和refresh_token保存起来(例如在localStorage、sessionStorage或Cookie中)。API 请求
在每次调用需要认证的 API 时,在 HTTP 请求头中加入
Authorization: Bearer <access_token>。处理 Token 过期
发起 API 请求,如果返回 401 错误,说明
access_token可能过期了。前端自动(或提示用户)调用
/api/token/refresh/接口,使用refresh_token获取新的access_token。用新的
access_token重试失败的请求。
用户退出登录
前端直接丢弃存储的
token即可。
JWT认证流程实现
用户登录获取JWT
# views.py from rest_framework.views import APIView from rest_framework.response import Response from rest_framework_simplejwt.tokens import RefreshToken from django.contrib.auth import authenticate class UserLoginAPIView(APIView): def post(self, request): username = request.data.get('username') password = request.data.get('password') # 验证用户凭证 user = authenticate(username=username, password=password) if user: # 生成 JWT token refresh = RefreshToken.for_user(user) return Response({ 'access': str(refresh.access_token), 'refresh': str(refresh), 'user_id': user.id, 'username': user.username }) else: return Response({'error': 'Invalid credentials'}, status=400)客户端存储和发送JWT
客户端在登录成功后,将 JWT 存储在本地(通常是在 localStorage 或 cookie 中),并在后续请求的 Header 中携带:
// 前端示例 // 存储 token localStorage.setItem('access_token', response.data.access); // 在请求头中携带 token axios.get('/api/protected-resource/', { headers: { 'Authorization': `Bearer ${localStorage.getItem('access_token')}` } });Django 配置JWT认证
# settings.py REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework_simplejwt.authentication.JWTAuthentication', ), } # JWT 配置 SIMPLE_JWT = { 'ACCESS_TOKEN_LIFETIME': timedelta(minutes=60), 'REFRESH_TOKEN_LIFETIME': timedelta(days=1), 'AUTH_HEADER_TYPES': ('Bearer',), }访问需要认证的视图
# views.py from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.permissions import IsAuthenticated class ProtectedView(APIView): permission_classes = [IsAuthenticated] def get(self, request): # 此时 request.user 就是认证后的用户对象 user = request.user return Response({ 'message': f'Hello {user.username}', 'user_id': user.id, 'email': user.email })url配置
# urls.py from django.urls import path from rest_framework_simplejwt.views import TokenRefreshView from .views import LoginView, ProtectedView urlpatterns = [ path('api/login/', LoginView.as_view(), name='login'), path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), path('api/protected/', ProtectedView.as_view(), name='protected'), ]
