DRF 请求对象 #
一、Request对象概述 #
1.1 什么是Request #
DRF的Request对象扩展了Django的HttpRequest,提供了更方便的API数据处理功能。
text
Request继承关系
┌─────────────────────────────────────┐
│ Django HttpRequest │
│ - GET, POST, META等属性 │
│ - 原始请求数据 │
└─────────────────────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ DRF Request │
│ - data: 解析后的请求体 │
│ - query_params: 查询参数 │
│ - user: 认证用户 │
│ - auth: 认证信息 │
└─────────────────────────────────────┘
1.2 核心属性 #
| 属性 | 说明 |
|---|---|
| data | 解析后的请求体数据 |
| query_params | 查询参数 |
| user | 认证用户 |
| auth | 认证信息 |
| method | HTTP方法 |
| content_type | 内容类型 |
| stream | 原始请求流 |
二、request.data #
2.1 基本用法 #
python
from rest_framework.views import APIView
from rest_framework.response import Response
class ArticleView(APIView):
def post(self, request):
title = request.data.get('title')
content = request.data.get('content')
return Response({
'title': title,
'content': content
})
2.2 数据类型 #
python
class DataView(APIView):
def post(self, request):
print(type(request.data))
if isinstance(request.data, dict):
for key, value in request.data.items():
print(f'{key}: {value}')
return Response({'received': True})
2.3 与POST的区别 #
python
class CompareView(APIView):
def post(self, request):
return Response({
'data': request.data,
'POST': request.POST,
'data_keys': list(request.data.keys()),
'POST_keys': list(request.POST.keys())
})
| 特性 | request.data | request.POST |
|---|---|---|
| 支持格式 | JSON, Form, MultiPart | 仅Form数据 |
| 解析方式 | 自动解析 | Django原生 |
| 返回类型 | dict | QueryDict |
三、query_params #
3.1 基本用法 #
python
class SearchView(APIView):
def get(self, request):
keyword = request.query_params.get('keyword', '')
page = request.query_params.get('page', 1)
page_size = request.query_params.get('page_size', 10)
return Response({
'keyword': keyword,
'page': page,
'page_size': page_size
})
3.2 获取多个值 #
python
class FilterView(APIView):
def get(self, request):
categories = request.query_params.getlist('category')
tags = request.query_params.getlist('tag')
return Response({
'categories': categories,
'tags': tags
})
3.3 类型转换 #
python
class TypedParamsView(APIView):
def get(self, request):
try:
page = int(request.query_params.get('page', 1))
page_size = int(request.query_params.get('page_size', 10))
is_active = request.query_params.get('is_active', 'true').lower() == 'true'
except ValueError:
return Response({'error': '参数类型错误'}, status=400)
return Response({
'page': page,
'page_size': page_size,
'is_active': is_active
})
四、请求头 #
4.1 获取请求头 #
python
class HeadersView(APIView):
def get(self, request):
content_type = request.META.get('CONTENT_TYPE')
authorization = request.META.get('HTTP_AUTHORIZATION')
user_agent = request.META.get('HTTP_USER_AGENT')
return Response({
'content_type': content_type,
'authorization': authorization,
'user_agent': user_agent
})
4.2 request.headers #
python
class HeadersView(APIView):
def get(self, request):
headers = request.headers
return Response({
'content_type': headers.get('Content-Type'),
'authorization': headers.get('Authorization'),
'user_agent': headers.get('User-Agent'),
'all_headers': dict(headers)
})
五、文件上传 #
5.1 单文件上传 #
python
class FileUploadView(APIView):
def post(self, request):
file = request.FILES.get('file')
if not file:
return Response({'error': '请选择文件'}, status=400)
file_info = {
'name': file.name,
'size': file.size,
'content_type': file.content_type,
}
return Response(file_info)
5.2 多文件上传 #
python
class MultiFileUploadView(APIView):
def post(self, request):
files = request.FILES.getlist('files')
files_info = []
for file in files:
files_info.append({
'name': file.name,
'size': file.size,
'content_type': file.content_type,
})
return Response({'files': files_info})
5.3 保存文件 #
python
import os
from django.conf import settings
class FileUploadView(APIView):
def post(self, request):
file = request.FILES.get('file')
if not file:
return Response({'error': '请选择文件'}, status=400)
upload_dir = os.path.join(settings.MEDIA_ROOT, 'uploads')
os.makedirs(upload_dir, exist_ok=True)
file_path = os.path.join(upload_dir, file.name)
with open(file_path, 'wb+') as destination:
for chunk in file.chunks():
destination.write(chunk)
return Response({
'message': '上传成功',
'file_name': file.name,
'file_path': file_path
})
六、用户信息 #
6.1 获取用户 #
python
class UserView(APIView):
def get(self, request):
if request.user.is_authenticated:
return Response({
'user_id': request.user.id,
'username': request.user.username,
'email': request.user.email,
'is_staff': request.user.is_staff,
})
return Response({'user': 'anonymous'})
6.2 认证信息 #
python
class AuthView(APIView):
def get(self, request):
return Response({
'user': str(request.user),
'auth': str(request.auth),
'is_authenticated': request.user.is_authenticated,
})
七、请求方法 #
7.1 判断请求方法 #
python
class MethodView(APIView):
def get(self, request):
return Response({'method': request.method})
def post(self, request):
return Response({'method': request.method})
def put(self, request):
return Response({'method': request.method})
def patch(self, request):
return Response({'method': request.method})
def delete(self, request):
return Response({'method': request.method})
7.2 条件处理 #
python
class ConditionalView(APIView):
def get(self, request):
if request.method == 'GET':
return self.handle_get(request)
elif request.method == 'POST':
return self.handle_post(request)
def handle_get(self, request):
return Response({'action': 'get'})
def handle_post(self, request):
return Response({'action': 'post'})
八、内容协商 #
8.1 获取内容类型 #
python
class ContentView(APIView):
def post(self, request):
return Response({
'content_type': request.content_type,
'accepted_type': request.accepted_media_type,
'accepted_renderer': str(request.accepted_renderer),
})
8.2 原始请求流 #
python
class RawView(APIView):
def post(self, request):
raw_data = request.stream.read()
return Response({
'raw_data': raw_data.decode('utf-8'),
'content_type': request.content_type,
})
九、实用方法 #
9.1 获取客户端IP #
python
def get_client_ip(request):
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
if x_forwarded_for:
ip = x_forwarded_for.split(',')[0]
else:
ip = request.META.get('REMOTE_ADDR')
return ip
class IPView(APIView):
def get(self, request):
return Response({'ip': get_client_ip(request)})
9.2 获取User-Agent #
python
class UserAgentView(APIView):
def get(self, request):
user_agent = request.META.get('HTTP_USER_AGENT', '')
is_mobile = 'Mobile' in user_agent
is_ios = 'iPhone' in user_agent or 'iPad' in user_agent
is_android = 'Android' in user_agent
return Response({
'user_agent': user_agent,
'is_mobile': is_mobile,
'is_ios': is_ios,
'is_android': is_android,
})
9.3 请求日志 #
python
import logging
logger = logging.getLogger(__name__)
class LoggingView(APIView):
def post(self, request):
logger.info(f'Request from {get_client_ip(request)}')
logger.info(f'User: {request.user}')
logger.info(f'Method: {request.method}')
logger.info(f'Path: {request.path}')
logger.info(f'Data: {request.data}')
return Response({'logged': True})
十、总结 #
本章学习了DRF Request对象:
- request.data:解析后的请求体数据
- query_params:查询参数处理
- 请求头:获取HTTP头信息
- 文件上传:处理文件上传
- 用户信息:获取认证用户
让我们继续学习Response对象!
最后更新:2026-03-28