前后端开发模式
1.前后端不分离----全栈
涉及模板语法
2.前后端分离
2.1 前端测试工具:模仿发送http请求--postman
2.2 api接口:连接前后端的媒介
restful规范
1.使用https 安全性高
2.url中携带api标识
3.多数据版本共存 url中携带版本号
4.数据即资源 接口尽可能使用名词(可使用负数)
5.资源操作由请求方式决定
获取数据:get
修改数据:put、patch
增加数据:post
删除数据:delete
6.url中带过滤参数
7.响应状态码
http状态码:
1.x 正在请求中
2.x 请求成功
3.x 重定向
4.x 客户端有误
5.x 服务端有误
公司自己规定的状态码
8.返回错误信息 响应体中携带错误信息
9.返回的结果 针对不同的操作 服务器向用户返回的结果符合以下要求
GET/collection:返回资源对象的列表(数组)[{},{}]
GET/collection/resource:返回单个资源对象{}
POST/collection:返回新生成的资源对象{}
PUT/collection/resource:返回完整的资源对象
PATCH/collection/resource:返回完整的资源对象{}
DELETE/collection/resource:返回一个空文档
数据获取类型:获取所有
获取单条
新增数据
修改数据
删除数据
10.响应中带链接
序列化与反序列化
序列化:将我们能识别的语言转化为别人能识别的语言
反序列化:将别人能识别的语言转化为我们可以识别的语言
CBV的源码分析
1.(继承View)
从路由入手(类名.as_view()) 当路由匹配成功 执行类名.as_view()()
查找as_view方法 视图类中无 查找父类View中的as_view
执行父类View中的as_view方法 返回了view
视图函数就变成了类名.view()
查找view方法 视图类中无 查找到了父类View中的as_view下的闭包函数View
执行父类View中的as_view下的闭包函数View 执行了dispatch方法
dispatch方法将request传入并将请求类型转为小写 并通过反射getattr获取请求方式
执行请求方法
drf
CBV的源码分析
2.(继承APIView---继承了View)
从路由入手(类名.as_view()) 当路由匹配成功 执行类名.as_view()()
查找as_view方法 视图类中无 查找父类APIView中的as_view
执行父类APIView中的as_view 使用了View中的as_view方法 取消了csrf认证(装饰器的方法)
执行父类View中的as_view下的闭包函数View 执行了dispatch方法
查找dispatch方法 视图类中无 查找父类APIView中的dispatch方法
执行父类APIView中的dispatch方法 执行了三大认证 包装了新的request 全局异常捕获
dispatch方法将request传入并将请求类型转为小写 并通过反射getattr获取请求方式
序列化类
1.继承Serializer
校验
写序列化字段(字段 参数) 校验
需要重写creat与update方法
局部钩子
全局钩子
执行方法
视图类中继承APIView 写5个方法
路由:类名.as_view()
2.继承ModelSerializer
校验
也可以给字段设置别的字段与参数
类-class Meta:
model = 类名
# flides = '__all__' # 相当于将所有的字段序列化
# 数据校验
fildes = ['name', 'price',......]
extra_kwargs = {'name': {...}}
局部钩子
全局钩子
执行方法
视图类中继承APIView 写5个方法
路由:类名.as_view()
请求与响应
1.请求:Request:继承APIView之后 每一次请求的request都是新的
1.属性:data:POST/PUT/PATCH请求方式解析之后的数据
注:原生django put提交的数据在request.POST中无法获取
需要转成json格式字符串从body中获取
query_params:相当于原生django中的GET 使用方法一致
FILSE/method/path使用方法和原生django中一致
2.方法:GET/POST/PUT/delete
3.drf默认请求格式:在res_framework.settings中可以查询
DEFAULTS = {
'DEFAULT_PARSER_CLASSES': [
'rest_framework.parsers.JSONParser',
'rest_framework.parsers.FormParser',
'rest_framework.parsers.MultiPartParser'
4.配置响应格式
全局配置:项目配置文件
局部配置:视图类中
class BookView(APIView):
parser_classes = [JSONParser,FormParser,MultiPartParser]
5.解析的使用顺序:视图类--项目配置文件--内置配置文件
6.实际项目配置:基本上都运行JSONParser,FormParser
上传文件只允许MultiPartParser
2.响应:
1.属性:data:序列化成json格式的字符串返回给前端
status:http响应的状态码 drf将状态码做成了常量
headers:http的响应头
1.Response:REST framework提供的响应类 会将响应内容转换(rander)显示成符合前端需要的类型
根据请求头中的(Accept)接收数据响应来做转换 如果没有 采用默认方式
2.drf默认解析响应编码:在res_framework.settings中可以查询
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': [ # 默认响应渲染类
'rest_framework.renderers.JSONRenderer', # json渲染器
'rest_framework.renderers.TemplateHTMLRenderer', # 浏览器API渲染器
],
3.配置响应格式
全局配置:项目配置文件中修改
DEFAULTS = {
# Base API policies
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer', # json格式
'rest_framework.renderers.BrowsableAPIRenderer', # 浏览器看到的格式
],
局部配置:视图类中
class BookView(APIView):
renderer_classes = [JSONRenderer,]
运行顺序:局部---全局---默认
4.属性:
data:为响应准备的序列化处理后的数据
status:状态码 默认200 常量(可以直接导入) (status_code:状态码的数字)
1xx---信息告知
2xx---成功
3xx---重定向
4xx---客户端错误
5xx---服务器错误
headers:存放响应头的字典
content_type:响应数据类型 可以设置参数 (content经过rander处理后的响应数据)
template_name:模板的名称
5.响应头中添加数据
5.1 原生django中向响应头中添加数据:
class User(views.View):
def get(self, request):
b = {'name': 'lili'}
res = JsonResponse(b)
# res['age'] = 19
res['name'] = 'haha'
return res
5.2 drf中向响应头中添加数据:通过Response的属性headers={'name': 'lili'}添加
class BookViews(APIView):
def get(self, request):
book_list = models.Book.objects.all()
ser = serializer.BookSerializer(instance=book_list, many=True)
return Response(ser.data, headers={'name': 'lili'})
6.解析的使用顺序:视图类--项目配置文件--内置配置文件
7.实际编码中响应一般是默认
视图层
2个基类
1.APIView:
2.GenericAPIView:继承了APIView
类属性:queryset = models.Book.objects.all()
serializer_class = serializer.BookSerializer
方法: self.get_object() # 根据pk获取单个数据
self.get_serializer # 获取要使用的序列化类
self.get_queryset() # 获取所有要序列化数据
5个扩展类
3.2 5个扩展类:ListModelMixin/CreateModelMixin/RetrieveModelMixin/ UpdateModelMixin/DestroyModelMixin
class BookView(GenericAPIView, ListModelMixin, CreateModelMixin):
queryset = models.Book.objects.all()
serializer_class = serializers.BookSerializer
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
class BookDetailView(GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin):
queryset = models.Book.objects.all()
serializer_class = serializers.BookSerializer
def get(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs)
def put(self, request, *args, **kwargs):
return self.update(request, *args, **kwargs)
def delete(self, request, *args, **kwargs):
return self.destroy(request, *args, **kwargs)
9个子类
1.ListAPIView
2.CreateAPIView
3.RetrieveAPIView
4.UpdateAPIView
5.DestroyAPIView
6.ListCreateAPIView
7.RetrieveUpdateDestroyAPIView
8.RetrieveUpdateAPIView
9.RetrieveDestroyAPIView
class BookView(ListCreateAPIView):
queryset = models.Book.objects.all()
serializer_class = serializers.BookSerializer
class BookDetailView(RetrieveUpdateDestroyAPIView):
queryset = models.Book.objects.all()
serializer_class = serializers.BookSerializer
视图集
from rest_framework.viewsets import ModelViewSet
class BookView(ModelViewSet ):
queryset = models.Book.objects.all()
serializer_class = serializers.BookSerializer
路由:urlpatterns =
path('books/', views.BookView.as_view({'get': 'list', 'post': 'create'})),
path('books/<int:pk>', views.BookView.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'}))
源码分析ViewSetMixin
@classonlymethod
def as_view(cls, actions=None, **initkwargs):
# 路由中as_view中必须传参数,必须传字典:{'get': 'list', 'post': 'create'}
if not actions:
raise TypeError("The `actions` argument must be provided when "
"calling `.as_view()` on a ViewSet. For example "
"`.as_view({'get': 'list'})`")
# 路由匹配成功,执行view(request),request是老的request
def view(request, *args, **kwargs):
# actions={'get': 'list', 'post': 'create'}
for method, action in actions.items():
# method:get action:list
# self 是视图类的对象中通过反射,查找list,
# handler视图类中的list方法
handler = getattr(self, action)
# 向视图类的对象中,反射 method:get,handler:list方法
# self.get=list
setattr(self, method, handler)
return self.dispatch(request, *args, **kwargs)
return csrf_exempt(view)
注:只要继承了ViewSetMixin,以后路由写法变量,都要协程:views.UserView.as_view({'get': 'list', 'post': 'create'}))
以后只要继承了ViewSetMixin,视图类中可以写任意名字的方法,不用非得写get,post,delete
标签:get,self,request,视图,drf,class,view
From: https://www.cnblogs.com/040714zq/p/16760132.html