文章目录
一、请求Request
REST framework 传入视图的request对象不再是Django默认的HttpRequest对象,而是REST framework提供的扩展了HttpRequest类的Request类的对象。
1.对象路径
from rest_framework.request import Request
分析源码:
from rest_framework.request import Request
class Request:
def __init__(self, request, parsers=None, authenticators=None,
negotiator=None, parser_context=None):
# 二次封装request,将原生request作为drf中request对象的 _request 属性
self._request = request
def __getattr__(self, item):
return getattr(self._request, item)
# 请求对象: request.data 前端以三种编码方式传入的数据,都可以取出来
# 请求对象: request.query_params与Django标准的request.GET相同,只是更换了更正确的名称而已。
2.常用属性
-
request.data
:返回解析之后的请求体数据,类似于Django中标准的request.POST
和request.FILES
属性,但提供如下特性:data 特征
- 包含了解析之后的文件和非文件数据
- 包含了对
POST
、PUT
、PATCH
请求方式解析后的数据 - 利用了REST framework的parsers解析器,不仅支持表单类型数据,也支持JSON数据
-
request..query_params
:与Django标准的request.GET
相同,只是更换了更正确的名称而已。
3.配置能够解析的请求编码格式 : parser_classes
全局配置
- 在
settings.py
文件中配置如下:
REST_FRAMEWORK = {
'DEFAULT_PARSER_CLASSES': [
'rest_framework.parsers.JSONParser',
'rest_framework.parsers.FormParser',
'rest_framework.parsers.MultiPartParser'
]
}
只能够解析三种请求编码格式:
JSON
、FormDate
、urlencoded
局部配置
- 在单独某个视图类中配置:
parser_classes = [FormParser]
配置该项, 视图类首先是先查找自己类中是否有该配置
二、响应Response
1.对象路径
from rest_framework.response import Response
源码分析
from rest_framework.response import Response
class Response:
def __init__(self, data=None, status=None,
template_name=None, headers=None,
exception=False, content_type=None):
"""
:param data: 你要返回的数据,字典
:param status: 返回的状态码,默认是200,
from rest_framework import status # 在这个路径下, 它把所有使用到的状态码都定义成了常量
:param template_name: 渲染的模板名字(自定制模板),不需要了解
:param headers: 响应头,可以往响应头放东西,就是一个字典
:param content_type: 响应的编码格式,application/json 和 text/html
"""
2.常用属性
-
data
:为响应准备的序列化处理后的数据(字典) -
headers
: 用于存放响应头信息的字典 -
status
: 状态码, 默认200 (http请求的状态码) -
template_name
: 模板名称, 如果使用HTMLRenderer 时需指明 -
content_type
: 响应数据的Content-Type, 通常此参数无需传递, REST framework会根据前端所需类型数据来设置该参数
三、配置响应格式
1.两种显示格式
- 我们使用浏览器访问 DRF 时, 返回的是一个页面
- 如果使用 Postman 这样的软件访问, 那么展示的就是 JSON 格式, ajax 请求也是 JSON格式
2.配置响应格式 : renderer_classes
配置的加载执行顺序
- 先从自己类中找——》项目的setting中找——》默认配置文件中找
全局配置
- 在settings.py文件中进行配置
# 在 settings.py 文件中进行配置
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': ( # 默认响应渲染类
'rest_framework.renderers.JSONRenderer', # json渲染器
'rest_framework.renderers.BrowsableAPIRenderer', # 浏览API渲染器
)
}
局部配置
- 在某个视图类中进行配置
# 在某个视图类中进行配置
from rest_framework.renderers import JSONRenderer
renderer_classes=[JSONRenderer,]
四、状态码
为了方便设置状态码,REST framewrok在rest_framework.status
模块中提供了常用状态码常量。
导入status模块
from rest_framework import status
# "status." 点可取状态码
# 默认响应状态码 : 200
1xx:信息告知
HTTP_100_CONTINUE
HTTP_101_SWITCHING_PROTOCOLS
2xx:成功
HTTP_200_OK
HTTP_201_CREATED
HTTP_202_ACCEPTED
HTTP_203_NON_AUTHORITATIVE_INFORMATION
HTTP_204_NO_CONTENT
HTTP_205_RESET_CONTENT
HTTP_206_PARTIAL_CONTENT
HTTP_207_MULTI_STATUS
3xx:重定向
HTTP_300_MULTIPLE_CHOICES
HTTP_301_MOVED_PERMANENTLY
HTTP_302_FOUND
HTTP_303_SEE_OTHER
HTTP_304_NOT_MODIFIED
HTTP_305_USE_PROXY
HTTP_306_RESERVED
HTTP_307_TEMPORARY_REDIRECT
4xx:客户端错误
HTTP_400_BAD_REQUEST
HTTP_401_UNAUTHORIZED
HTTP_402_PAYMENT_REQUIRED
HTTP_403_FORBIDDEN
HTTP_404_NOT_FOUND
HTTP_405_METHOD_NOT_ALLOWED
HTTP_406_NOT_ACCEPTABLE
HTTP_407_PROXY_AUTHENTICATION_REQUIRED
HTTP_408_REQUEST_TIMEOUT
HTTP_409_CONFLICT
HTTP_410_GONE
HTTP_411_LENGTH_REQUIRED
HTTP_412_PRECONDITION_FAILED
HTTP_413_REQUEST_ENTITY_TOO_LARGE
HTTP_414_REQUEST_URI_TOO_LONG
HTTP_415_UNSUPPORTED_MEDIA_TYPE
HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE
HTTP_417_EXPECTATION_FAILED
HTTP_422_UNPROCESSABLE_ENTITY
HTTP_423_LOCKED
HTTP_424_FAILED_DEPENDENCY
HTTP_428_PRECONDITION_REQUIRED
HTTP_429_TOO_MANY_REQUESTS
HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE
HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS
5xx:服务端错误
HTTP_500_INTERNAL_SERVER_ERROR
HTTP_501_NOT_IMPLEMENTED
HTTP_502_BAD_GATEWAY
HTTP_503_SERVICE_UNAVAILABLE
HTTP_504_GATEWAY_TIMEOUT
HTTP_505_HTTP_VERSION_NOT_SUPPORTED
HTTP_507_INSUFFICIENT_STORAGE
HTTP_511_NETWORK_AUTHENTICATION_REQUIRED
五、封装自己的Response对象
1.无自定义,手动创建
- views.py
class Test1(APIView):
def get(self,request):
response = {'status':200,'msg':None}
# 写一堆逻辑,下面伪代码
res = 1
if res:
response['msg'] = '成功'
response['data'] = {'name':'shawn','age':99}
else:
response['status'] = 201
response['msg'] = '失败'
return Response(response)
- urls.py
path('test1/', views.Test1.as_view()),
2.自定义Response类(初始版)
- myresponse.py文件(自行创建)
class MyResponse():
def __init__(self):
self.status = 200
self.msg = None
@property
def get_dict(self):
return self.__dict__
- views.py
from mydrf.myresponse import MyResponse
class Test2(APIView):
def get(self,request):
# 先实例化得到响应对象
response = MyResponse()
# 写一堆逻辑,下面伪代码
res = 1
if not res:
# 直接以的.点方式设置属性
response.status = 201
response.msg = '失败了'
# 返回响应字典
response.msg = '成功了'
return Response(response.get_dict)
- urls.py
path('test2/', views.Test2.as_view()),
3.自定义Response类(高级版)
- myresponse.py 文件
from rest_framework.response import Response
class APIResponse(Response):
# 继承 Response 类,并将其内的参数全部拿过来,然后添加自定义的参数(属性)
# 设置一个kwargs接收其余关键字参数
def __init__(self, code=200, msg=None, data=None, status=None,
template_name=None, headers=None,
exception=False, content_type=None, **kwargs):
dic = {'static': code, 'msg': msg}
if data:
dic['data'] = data # 将data数据放在"data"键中
if kwargs:
dic.update(kwargs) # 将kwargs接收的位置参数更新入dic中
# 调用父类的__init__方法进行初始化
super().__init__(data=dic, status=status,
template_name=template_name, headers=headers,
exception=exception, content_type=content_type)
- view.py
from mydrf.myresponse import APIResponse
class Test3(APIView):
def get(self, request):
# 写一堆逻辑,下面伪代码
res = 1
if res:
return APIResponse(msg='成功!', data={'name': 'shawn'}, next='/index/')
return APIResponse(status=201, msg='失败', next='/login/')
- urls.py
path('test3/', views.Test3.as_view()),