一、Drf请求与响应
1.Request类和Response类
Request类
REST FrameWork传入视图的Request对象不再是Django默认的HttpRequest对象 而是REST FrameWork提供的扩展了HttpResponse类的Request类的对象了 Rest FrameWork提供了Parser 解析器 在接收到请求后自动根据Content-type 指明的数据类型(默认是JSON) 将请求数据进行Parse解析 解析为字典[QueryDict] 对象保存到Request对象 中 Request对象的数据是自动根据前端发送数据的格式进行解析之后的结果 无论前端发送的哪种格式数据 我们都可以用同一个一种方式读取数据
属性data request.data 返回解析之后的请求题数据 类似于Django中的request.POST 和request.FILES 属性
- 包含了解析之后的文件和非文件数据
- 包含了对POST、PUT、PATCH请求方式解析后的数据
- 利用了REST FrameWork的Parsers解析器 不仅仅支持表单类型数据 也支持JSON数据
属性query_params request.query_params 与Django标准的request.GET 相同 只是更换了更正确的名称
Response类
Response(data=None, status=None,template_name=None, headers=None,exception=False, content_type=None)
REST FrameFork提供了一个响应类Response 使用该类构造响应对象时 响应的具体数据内容会被转换(render渲染)成符合前端需求的类型 REST FrameFork提供了Renderer 渲染器 用来根据请求投中的Accept 接收数据类型声明 来自动转换响应数据到对应格式 如果前端请求中未进行Accept声明 则会采用默认方式处理响应数据 我们可以通过配置来修改默认响应格式 可以在rest_framework.settings 查找所有的drf默认配置项
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': (
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
)
}
参数说明:
- data 为响应准备的序列化处理后的数据
- status 状态码默认200
- template_name 模版名称 如果使用HTML Renderer时需要指定
- headers 用于存放响应头信息的字典
- content_type 响应数据的Content_type 通常此参数无需传递 REST FrameWork会根据前端所需类型数据来设置该参数
常用属性
- data 传给response对象的序列化后 但还没有给render处理的数据
- status_code 状态码数字
- content 经过render处理后的响应数据
状态码 1)信息告知 -1xx
HTTP_100_CONTINUE
HTTP_101_SWITCHING_PROTOCOLS
2)成功 -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
3)重定向 -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
4)客户端错误 -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
5)服务器错误 -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
2.Drf能够解析的请求编码与相应编码
默认能解析的请求编码 默认能解析(urlencoded、form-data、json) 项目中没有配置 是在Drf内置的配置文件中 提前配置好了 Drf的配置文件settings.py中有
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.TemplateHTMLRenderer',
],
'DEFAULT_PARSER_CLASSES': [
'rest_framework.parsers.JSONParser',
'rest_framework.parsers.FormParser',
'rest_framework.parsers.MultiPartParser',
],
}
如果我们想我们的接口只能接受Json格式呢?
方式1: 全局配置>项目配置文件
REST_FRAMEWORK = {
'DEFAULT_PARSER_CLASSES': [
'rest_framework.parsers.JSONParser',
],
}
方式2: 局部配置
from rest_framework.parsers import JSONParser, Formparser, Multipartparser
class TestView(APIView):
parser_classes = [JSONParser,FormParser,MultiPartParser]
'''
-总结:
-解析类的使用顺序:优先用视图类自己的 然后用项目配置文件,最后用内置的
-实际项目如何配置
-基本上都运行JSONParser,FormParser -如果上传文件只允许MultiPartParser
'''
响应编码 如果想用浏览器看到DRF美化的样子 如果用postman看到json格式数据的样子 -默认情况下 响应的编码是根据客户端类型决定的
如果我们想无论用什么访问都返回json格式呢?跟上面一样两种方式!
全局配置:
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.BrowsableAPIRenderer',
]
}
局部配置:
from rest_framework.renderers import JSONRenderer, BrowsableAPIRenderer
class TestView(APIView):
renderer_classes = [JSONRenderer,]
二、Drf视图组件
由于Drf提供了一个顶层的视图类APIView 咱们可以通过继承APIView写视图类
后期咱们要写的代码可能重复代码比较多 就可以使用面向对象的继承 封装
class MovieView(APIView):
def get(self, request):
movie_list = Movie.objects.all()
ser = MovieSerializers(instance=movie_list, many=True)
return Response(ser.data)
def post(self, request):
ser = MovieSerializers(data=request.data)
if ser.is_valid():
ser.save()
return Response({'code': 100, 'msg': '新增成功'})
else:
return Response({'code': 101, 'msg': ser.errors})
class MovieDetailView(APIView):
def get(self, request, pk):
movie = Movie.objects.filter(pk=pk).first()
ser = MovieSerializers(instance=movie)
return Response(ser.data)
def put(self, request, pk):
movie = Movie.objects.filter(pk=pk).first()
ser = MovieSerializers(instance=movie, data=request.data)
if ser.is_valid():
ser.save()
return Response({'code': 100, 'mgs': '修改成功'}, status=201)
else:
return Response({'code': 101, 'mgs': ser.errors})
def delete(self, request, pk):
Movie.objects.filter(pk=pk).delete()
return Response()
四、Drf视图基类
# APIView
GenericAPIView-->继承了APIView
-类属性:
queryset = User.objects.all()
serializer_class = UserSerializer
-方法:
self.get_object() # 根据pk获取单个数据
self.get_serializer # 获取要使用的序列化类
self.get_queryset() # 获取所有要序列化数据
1.基于APIView写5个接口
'''基于APIView写五个接口其实就是上面已经写过的接口'''
class MovieView(APIView):
def get(self, request):
movie_list = Movie.objects.all()
ser = MovieSerializers(instance=movie_list, many=True)
return Response(ser.data)
def post(self, request):
ser = MovieSerializers(data=request.data)
if ser.is_valid():
ser.save()
return Response({'code': 100, 'msg': '新增成功'})
else:
return Response({'code': 101, 'msg': ser.errors})
class MovieDetailView(APIView):
def get(self, request, pk):
movie = Movie.objects.filter(pk=pk).first()
ser = MovieSerializers(instance=movie)
return Response(ser.data)
def put(self, request, pk):
movie = Movie.objects.filter(pk=pk).first()
ser = MovieSerializers(instance=movie, data=request.data)
if ser.is_valid():
ser.save()
return Response({'code': 100, 'mgs': '修改成功'}, status=201)
else:
return Response({'code': 101, 'mgs': ser.errors})
def delete(self, request, pk):
Movie.objects.filter(pk=pk).delete()
return Response()
2.基于GenericAPIView写五个接口
from rest_framework.generics import GenericAPIView
class UserView(GenericAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
def get(self, request):
user_list = self.get_queryset()
ser = self.serializer_class(instance=user_list, many=True)
return Response(ser.data)
def post(self, request):
ser = self.get_serializer(data=request.data)
if ser.is_valid():
ser.save()
return Response({'code': 100, 'msg': '新增成功'}, status=201)
else:
return Response({'code': 101, 'msg': ser.errors})
class UserDetailView(GenericAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
def get(self, request, pk):
user = self.get_object()
ser = self.get_serializer(instance=user)
return Response(ser.data)
def put(self, request, pk):
user = self.get_object()
ser = self.get_serializer(instance=user, data=request.data)
if ser.is_valid():
ser.save()
return Response({'code': 100, 'msg': '修改成功', }, status=201)
else:
return Response({'code': 101, 'msg': ser.errors})
def delete(self, reqeust, pk):
self.get_queryset().filter(pk=pk).delete()
return Response('')
技术小白记录学习过程,有错误或不解的地方请指出,如果这篇文章对你有所帮助请点点赞收藏+关注 谢谢支持 !!!
|