一、drf入门流程
- 前后端开发模式
- API接口
- postman使用
- 序列化和反序列化
- restful规范
- drf:第三方app—快速实现符合restful规范的接口
- 以后写的都是视图类 都是继承APIView及其子类
- cbv的执行流程
-路由中:视图类.(as_view)——View的as_view类的绑定方法——闭包函数view
-请求来了:执行闭包函数view(request)——self.dispatch(request,*args,**kwargs)
-View.dispatch:根据请求的方式,执行视图函数中以请求方式命名的方法
补充小知识点:
反射:通过字符串动态的获取,设置,判断,对象中的属性或者方法
-getattr res=getattr(self,'run',None)
-setattr setattr(self,'speak',内存地址) self.speak()
-hasattr hasattr('self','run')
- APIView继承了View,执行流程
-APIView的as_view了:1、调用父类的as_view 2、去掉了csrf
-请求来了 执行View的as_view的闭包view——dispatch
-APIView的dispatch
-1、包装了新的request
-2、在执行视图函数之前:执行了三大认证
-3、执行了视图函数:请求方式是什么,就执行视图函数中得什么方法
-4、全局异常捕获:全局异常,统一返回格式
- 序列化类
-Serializer
-ModelSerializer
-序列化
-反序列化
-校验
- 请求与响应
-Request类:属性和方法
-Response类
- 视图层(2基类、5个扩展类、9个子类、视图集)
- 路由的使用
- 认证、频率、权限
- 过滤、排序、分页
- 全局异常处理
- 接口文档:自定生成,自己写
- 前后端分离:jwt认证方式—登录
- 公司内部:RBAC
- django:admin美化
二、drf之请求与响应
2.1 Request和Response类
继承APIView后,请求对象:requets—每一次请求都是一个新的request
Request类:属性或方法
-data:POST、PUT、PATCH请求方式解析后的数据
原生django,put提交的数据在request.POST中是取不到的
-query_params
其他的用起来跟之前一样用(FILES,method,path...)—底层原理__getattr__
Response类
掌握项
data=None 字典、列表—序列化成json格式字符串,返回给前端(放在http响应的body中)
status=None http响应的状态码,默认是200,201
drf把所有的http响应状态码都做成了常量,可以直接导进来用
headers=None http的响应头、字典 {name:curry}
原生django要在响应头中加数据
res=JsonResponse(d)
res['xxx']='ooo'
return res
了解项
template_name = None 在浏览器中看到好看的页面,指定的模板
content_type = None 响应的编码格式(json)
2.2drf能够解析的请求编码,响应编码
请求编码
默认解析
urlencoded
form_data
json
那么问题来了,为什么会默认解析呢?
其实是通过配置完成:项目中没有配置,是在drf内置的配置文件中提前配好了
drf也是有两套,一套是项目中的配置(settings.py),一套是默认的配置
drf的配置文件settings.py中有DEFAULT_PARSER_CLASSES(默认的解析类)
'rest_framework.parsers.JSONParser', 可以解析json格式
'rest_framework.parsers.FormParser', 可以解析urlencoded格式
'rest_framework.parsers.MultiPartParser' 可以解析form-data格式
自定义我们的接口接受什么数据格式?一共两个方式
方式一、全局配置
在项目配置文件settings.py中修改配置,以后所有的接口都遵循这个配置
REST_FRAMEWORK = {
'DEFAULT_PARSER_CLASSES': [
'rest_framework.parsers.JSONParser',
'rest_framework.parsers.FormParser',
'rest_framework.parsers.MultiPartParser',
],
}
'''不用哪个数据格式就把他注释掉就可以实现了'''
方式二、局部配置
方式二:局部配置
class TestView(APIView):
parser_classes = [JSONParser, FormParser, MultiPartParser]
'''视图类中固定写法,用哪个数据格式就写在中括号里'''
总结:
解析类的使用顺序:优先用视图类自己的,然后用项目配置文件,最后用内置的
实际项目如何配置
-基本上都运行JSONParser,FormParser
-如果上传文件只允许MultiPartParser
响应编码
如果用浏览器,就能看到好看的样子,如果用postman看到json格式
-默认请情况下,响应的编码是根据客户端类型决定的
# 全局配置:在项目的配置文件
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer', # json格式
'rest_framework.renderers.BrowsableAPIRenderer', #浏览器的格式
]
}
# 局部配置:
class TestView(APIView):
renderer_classes = [JSONRenderer, BrowsableAPIRenderer]
实际编码中,响应一般不配置,就用默认的。
drf之视图组件
由于drf提供了一个顶层的视图类APIView,咱们可以通过继承APIView写视图类,后期咱们要写的代码可能重复代码比较多,就可以使用面向对象的继承,封装。
两个视图基类
- APIView
rest_framework.views.APIView APIView是REST framework提供的所有视图的基类,继承自Django的View父类。 APIView与View的不同之处在于: 1)传入到视图方法中的是REST framework的Request对象,而不是Django的HttpRequeset对象; 2)视图方法可以返回REST framework的Response对象,视图会为响应数据设置(render)符合前端要求的格式; 3)任何APIException异常都会被捕获到,并且处理成合适的响应信息; 4)在进行dispatch()分发前,会对请求进行身份认证、权限检查、流量控制。
- GenericAPIView
GenericAPIView继承了APIView
类属性:
1)queryset 指明使用的数据查询集
queryset = User.objects.all()
2)serializer_class 指明视图使用的序列化器
serializer_class = UserSerializer
方法:
self.get_object() # 根据pk获取单个数据
self.get_serializer() # 获取要使用的序列化类
self.get_queryset() # 获取所有要序列化数据
- 基于APIView写5个接口
from rest_framework.views import APIView
class UserView(APIView):
def get(self, request):
book_list = User.objects.all()
ser = UserSerializer(instance=book_list, many=True)
return Response(ser.data)
def post(self, request):
ser = UserSerializer(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(APIView):
def get(self, request, pk):
book = User.objects.filter(pk=pk).first()
ser = UserSerializer(instance=book)
return Response(ser.data)
def put(self, request, pk):
book = User.objects.filter(pk=pk).first()
ser = UserSerializer(instance=book, 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, request, pk):
User.objects.filter(pk=pk).delete()
return Response('')
- 基于GenericAPIView写5个接口
from rest_framework.generics import GenericAPIView class UserView(GenericAPIView): queryset = User.objects.all() serializer_class = UserSerializer def get(self, request): book_list = self.get_queryset() ser = self.get_serializer(instance=book_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): book = self.get_object() ser = self.get_serializer(instance=book) return Response(ser.data) def put(self, request, pk): book = self.get_object() ser = self.get_serializer(instance=book, 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, request, pk): self.get_queryset().filter(pk=pk).delete() return Response('')
标签:ser,APIView,self,request,视图,学习,Response,drf From: https://www.cnblogs.com/zzjjpp/p/16742106.html