一、请求对象的区别 1. Django 中的请求对象 通过 Django
进行项目开发时,视图层方法或者视图类中的方法都会接收一个 request
对象参数
1 2 3 4 from django.http import JsonResponsedef query_user (request ): return JsonResponse("OK" )
该 request
对象是 django.core.handlers.wsgi.WSGIRequest
类的对象,其中包含了请求相关的所有数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 def query_user (request ): request.method request.POST request.GET request.body return JsonResponse("OK" )
虽然可以满足大多数开发场景,但原始的 request
对象还是有很多用着不方便的地方,以 POST
请求举例:
当前端发送的请求头中 content-type: url-form-encoded
,参数为 v1=123&v2=456&v3=999
,django
一旦读取到该请求头,就会自动把请求参数解析为键值对格式,即 {"v1":123,"v2":456,"v3":999}
,并把解析后的值放在 request.POST
中,方便使用者调用;
当前端发送的请求头中 content-type: application/json
,参数为 {"v1":123,"v2":456,"v3":999}
时,django
是无法解析的,因此通过 request.POST
方法无法直接拿到数据,使用者必须从 request.body
中读出请求内容,再通过序列化操作以后才能拿到请求的参数。
2. DRF 中的请求对象 使用 drf
框架时,视图中的 request
对象是 rest_framework.request.Request
类的对象,其本质上是对 django
的 request
进行了一次封装优化,除了包含 django
原 request
对象相关的功能和属性以外,还丰富了其他的内容。
rest_framework.request.Request
类部分源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 class Request : """ Wrapper allowing to enhance a standard `HttpRequest` instance. Kwargs: - request(HttpRequest). The original request instance. (django中的request) - parsers(list/tuple). The parsers to use for parsing the request content. - authenticators(list/tuple). The authenticators used to try authenticating the request's user. """ def __init__ (self, request, parsers=None , authenticators=None ,negotiator=None , parser_context=None ): self ._request = request self .parsers = parsers or () self .authenticators = authenticators or () ... @property def query_params (self ): """ More semantically correct name for request.GET. """ return self ._request.GET @property def data (self ): if not _hasattr (self , '_full_data' ): self ._load_data_and_files() return self ._full_data def __getattr__ (self, attr ): try : return getattr (self ._request, attr) except AttributeError: return self .__getattribute__(attr)
rest_framework.request.Request
类的使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 from rest_framework.views import APIViewfrom rest_framework.response import Responseclass QueryUserView (APIView ): def get (self, request, *args, **kwargs ): request._request.method request._request.GET request._request.POST request._request.body request.query_params request.data request.method request.META request.path return Response("OK" )
二、源码剖析 drf
对 request
对象的再次封装的过程,可以通过源码来了解
第一步,当前前面的流程都走完,一直到执行 dispatch
方法这一步,dispatch
内部执行了一个 self.initialize_request
方法;
第二步,initialize_request
方法接收的参数 request
就是原来 django
中的 request
对象,将该参数传入 rest_framework.request.Request
类中,最后返回了一个该类的对象;
第三步,将 rest_framework.request.Request
类对象重新赋值给 self.request
,即 DRF
中视图层方法使用的 request
对象都是 rest_framework.request.Request
类的对象