Drf从入门到精通四(Drf请求与响应、Drf能够解析的请求编码与响应编码、Drf视图、Drf视图基类)

一、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.POSTrequest.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',    # JSON渲染器
        'rest_framework.renderers.BrowsableAPIRenderer',    # 浏览器API渲染器
    )
}

参数说明:

  • 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',		# 可以解析json格式
        'rest_framework.parsers.FormParser',		# 可以解析urlencoded格式
        'rest_framework.parsers.MultiPartParser',	# 可以解析form-data格式
    ],
}
如果我们想我们的接口只能接受Json格式呢?

方式1:	全局配置>项目配置文件

       	REST_FRAMEWORK = {
              'DEFAULT_PARSER_CLASSES': [
                  'rest_framework.parsers.JSONParser',
                  # 'rest_framework.parsers.FormParser',
                  # 'rest_framework.parsers.MultiPartParser',
              ],
          }
          
方式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.JSONRenderer', # json格式
            '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()
	        # instance表示要序列化的数据,many=True表示序列化多条(instance是qs对象,一定要传many=True)
	        ser = MovieSerializers(instance=movie_list, many=True)
	        return Response(ser.data)
	
	    def post(self, request):
	        ser = MovieSerializers(data=request.data)  # 从前端传递数据从request.data中取出来
	        if ser.is_valid():  # is_valid表示校验前端传入的数据 但是我们没有写入校验规则
	            ser.save()  # 这个时候发送post请求会发生报错 NotImplementedError: `create()` must be implemented.
	            # 这个时候点击我们点击save查看源码是调用了Save会触发BaseSerializer的方法
	            # 判断了 如果instance有值执行update,没有值执行create 看到create没有写 所以我们得重写Create
	
	            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()  # 跟上方的新增一样 我们需要去重写update方法
	            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()
	        # instance表示要序列化的数据,many=True表示序列化多条(instance是qs对象,一定要传many=True)
	        ser = MovieSerializers(instance=movie_list, many=True)
	        return Response(ser.data)
	
	    def post(self, request):
	        ser = MovieSerializers(data=request.data)  # 从前端传递数据从request.data中取出来
	        if ser.is_valid():  # is_valid表示校验前端传入的数据 但是我们没有写入校验规则
	            ser.save()  # 这个时候发送post请求会发生报错 NotImplementedError: `create()` must be implemented.
	            # 这个时候点击我们点击save查看源码是调用了Save会触发BaseSerializer的方法
	            # 判断了 如果instance有值执行update,没有值执行create 看到create没有写 所以我们得重写Create
	
	            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()  # 跟上方的新增一样 我们需要去重写update方法
	            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('')

技术小白记录学习过程,有错误或不解的地方请指出,如果这篇文章对你有所帮助请点点赞收藏+关注谢谢支持 !!!

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LoisMay

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值