1. 核心属性详解
DRF 的 Request 对象最重要的几个属性是:.data, .query_params, .user, .auth。
a. request.data - 解析后的请求体
这是 最常用 的属性,它返回解析后的请求正文内容。
- 自动解析:DRF 会根据请求的
Content-Type头(如application/json,application/x-www-form-urlencoded,multipart/form-data)自动调用相应的解析器 (Parser) 来处理request.body,你无需手动处理原始字节数据。 - 支持所有方法:无论请求方法是
POST,PUT, 还是PATCH,解析后的数据都统一放在request.data中。 - 数据类型:通常是一个
QueryDict或普通的字典(对于 JSON),处理方式与 Python 字典一致。
使用示例:
from rest_framework.views import APIView
from rest_framework.response import Response
class ArticleView(APIView):
def post(self, request):
# 假设客户端发送 JSON: {"title": "My Article", "content": "Hello World", "published": true}
title = request.data.get('title')
content = request.data.get('content')
is_published = request.data.get('published', False) # 提供默认值
# 创建文章逻辑 ...
# article = Article.objects.create(title=title, ...)
return Response({'id': article.id, 'title': title}, status=201)
def put(self, request, pk):
# 更新文章,request.data 包含要更新的字段
# 局部更新也可以用 patch 方法
article = Article.objects.get(pk=pk)
# ... 更新逻辑
return Response({'message': 'Updated'})
b. request.query_params - 查询参数
此属性用于获取 URL 中的查询字符串参数(即 ?key=value&key2=value2 部分)。
- 等同于 Django 的
request.GET:但命名为query_params更准确,因为它不仅用于GET请求,其他请求方法也可以带有查询参数。 - 数据类型:这是一个
QueryDict对象,可以像字典一样使用。
使用示例:
class ArticleListView(APIView):
def get(self, request):
# 处理 /api/articles/?page=2&search=drf&sort=-created_at
page_number = request.query_params.get('page', 1) # 获取 'page' 参数,默认为 1
search_query = request.query_params.get('search', '')
sort_order = request.query_params.get('sort', 'id')
# 使用这些参数进行过滤、分页和排序
articles = Article.objects.all()
if search_query:
articles = articles.filter(title__icontains=search_query)
articles = articles.order_by(sort_order)
# ... 序列化和分页逻辑
serializer = ArticleSerializer(articles, many=True)
return Response(serializer.data)
c. request.user 和 request.auth - 认证信息
这两个属性由 DRF 的认证系统自动填充。
request.user: 返回当前请求的用户对象。- 如果用户已认证,它是一个
User模型实例(或自定义用户模型)。 - 如果用户未认证,它是
AnonymousUser的一个实例。 - 你通常不需要手动检查
if request.user.is_authenticated:,而是通过配置权限类 (Permissions)(如IsAuthenticated)来让 DRF 在调用视图之前自动处理未认证的情况。
- 如果用户已认证,它是一个
request.auth: 用于存储额外的认证信息。- 在使用
TokenAuthentication时,request.auth是Token模型实例。 - 在使用
JWT时,request.auth是解码后的 token 内容(通常是一个字典)。 - 在其他认证方案中,它可能是
None。
- 在使用
使用示例:
from rest_framework.permissions import IsAuthenticated
class UserProfileView(APIView):
# 设置权限类,确保只有认证用户才能访问
permission_classes = [IsAuthenticated]
def get(self, request):
# 因为通过了权限检查,这里的 request.user 一定是认证用户
user = request.user
profile = user.profile
# ... 获取用户配置信息
return Response({'username': user.username, 'email': user.email})
def post(self, request):
# 可以使用 request.user 来关联创建对象
serializer = ArticleSerializer(data=request.data)
if serializer.is_valid():
# 将当前用户作为作者存入
serializer.save(author=request.user)
return Response(serializer.data, status=201)
return Response(serializer.errors, status=400)
2. 其他有用属性和方法
request.method: 获取 HTTP 请求方法(如'POST','GET')。注意:这实际上是底层 DjangoHttpRequest的属性,DRF 的Request对象通过代理暴露它。request.content_type: 获取请求体的媒体类型(如'application/json')。request.stream: 如果需要以流的形式处理请求体,可以访问此属性,但绝大多数情况下用不到,因为request.data已经处理好了。
3. 在序列化器中使用 request
在视图里,你可以将 request 中的信息(如当前用户)通过上下文 (context) 传递给序列化器。
class MyView(APIView):
permission_classes = [IsAuthenticated]
def post(self, request):
# 将 request 放入序列化器的上下文中
serializer = MyModelSerializer(
data=request.data,
context={'request': request} # 关键在这里!
)
if serializer.is_valid():
# 在序列化器的 create 或 update 方法中就可以通过 self.context['request'] 访问到 request 和 request.user
serializer.save()
return Response(serializer.data, status=201)
return Response(serializer.errors, status=400)
然后在序列化器中,你就可以使用这个上下文了:
class MyModelSerializer(serializers.ModelSerializer):
class Meta:
model = MyModel
fields = '__all__'
def create(self, validated_data):
# 从上下文中获取当前用户
request = self.context.get('request')
if request and hasattr(request, 'user'):
# 在创建对象时自动设置 owner 字段为当前用户
validated_data['owner'] = request.user
return super().create(validated_data)
4. 在哪种视图中可以使用?
DRF 的 Request 对象会在所有基于 DRF 的视图类中被自动创建和传递。这包括:
APIView的子类- 所有通用视图(
GenericAPIView,ListCreateAPIView, ...) - 视图集(
ViewSet,ModelViewSet, ...)
总结一下 DRF request 的使用要点:
- 读数据:用
request.data(请求体),用request.query_params(URL参数)。 - 用户认证:用
request.user,并配合权限类来保护视图,而不是在视图逻辑里手动检查。 - 传递上下文:需要在新创建的对象中关联当前用户或其他请求信息时,通过
context将request传递给序列化器,然后在序列化器的.create()或.update()方法中使用。 - 无需手动解析:永远不要再写
json.loads(request.body)这样的代码,DRF 已经为你做好了。
评论区 0