查漏补缺系列

解析器

request类

django的request类和rest-framework的request类的源码解析

局部视图

  1. from rest_framework.parsers import JSONParser,FormParser
  2. class PublishViewSet(generics.ListCreateAPIView):
  3. parser_classes = [FormParser,JSONParser]
  4. queryset = Publish.objects.all()
  5. serializer_class = PublshSerializers
  6. def post(self, request, *args, **kwargs):
  7. print("request.data",request.data)
  8. return self.create(request, *args, **kwargs)

全局视图

  1. REST_FRAMEWORK={
  2. "DEFAULT_AUTHENTICATION_CLASSES":["app01.service.auth.Authentication",],
  3. "DEFAULT_PERMISSION_CLASSES":["app01.service.permissions.SVIPPermission",],
  4. "DEFAULT_THROTTLE_CLASSES":["app01.service.throttles.VisitThrottle",],
  5. "DEFAULT_THROTTLE_RATES":{
  6. "visit_rate":"5/m",
  7. },
  8. "DEFAULT_PARSER_CLASSES":['rest_framework.parsers.FormParser',]
  9. }

备注:局部使用指定解析器时,只需在视图类中添加一个变量:parser_classes = [...]

rest_framework全局默认使用的解析器:

  1. DEFAULTS = {
  2. # Base API policies
  3.  
  4. 'DEFAULT_PARSER_CLASSES': (
  5. 'rest_framework.parsers.JSONParser',
  6. 'rest_framework.parsers.FormParser',
  7. 'rest_framework.parsers.MultiPartParser'
  8. ),

分页

简单分页

  1. from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination
  2.  
  3. class PNPagination(PageNumberPagination):
  4. page_size = 1 # 每页显示的数据个数
  5. page_query_param = 'page' #翻页的参数 ?page=num
  6. page_size_query_param = "size" #每页临时显示的数据个数 覆盖page_size
  7. max_page_size = 5 #每页允许显示的最大条数
  8.  
  9. class BookViewSet(viewsets.ModelViewSet):
  10.  
  11. queryset = Book.objects.all()
  12. serializer_class = BookSerializers
  13. def list(self,request,*args,**kwargs):
  14.      # 单写某个视图时的用法
  15. book_list=Book.objects.all()
  16. pp=LimitOffsetPagination()
  17. pager_books=pp.paginate_queryset(queryset=book_list,request=request,view=self)
  18. print(pager_books)
  19. bs=BookSerializers(pager_books,many=True)
  20.  
  21. #return Response(bs.data)
  22. return pp.get_paginated_response(bs.data)

偏移分页

  1. from rest_framework.pagination import LimitOffsetPagination

分页器在视图类中的用法:在视图类中定义一个变量: pagination_class=类

备注:使用LimitOffsetPagination偏移分页,里面的两个参数limit和offset:limit是每页显示的条数,offset是从第几条数据+1开始(offset=3,意为从第四条数据开始)。default_limit = num,默认显示的条数。

游标分页

  1. from rest_framework.views import APIView
  2. from .models import UserInfo
  3. from rest_framework.response import Response
  4. from rest_framework import serializers
  5. from rest_framework.pagination import CursorPagination
  6. class MyPagination(CursorPagination):
  7. # URL传入的游标参数
  8. cursor_query_param = 'cursor'
  9. # 默认每页显示的数据条数
  10. page_size = 2
  11. # URL传入的每页显示条数的参数
  12. page_size_query_param = 'page_size'
  13. # 每页显示数据最大条数
  14. max_page_size = 1000
  15.  
  16. # 根据ID从大到小排列
  17. ordering = "id"
  18. class PagerSerialize(serializers.ModelSerializer):
  19. '''数据序列化'''
  20. class Meta:
  21. model = UserInfo
  22. fields = "__all__"
  23. depth = 2 #用于显示关联字段的对应的表的详细内容
  24.  
  25. class PagerView(APIView):
  26. def get(self,request,*args,**kwargs):
  27. user_list=UserInfo.objects.all().order_by('-id') #将数据按照id从大到小排序
  28. #根据url参数,获取分页数据
  29. obj=MyPagination()
  30. page_user_list=obj.paginate_queryset(user_list,request,self)
  31.  
  32. #数据进行序列化
  33. ser=PagerSerialize(instance=page_user_list,many=True)
  34. response=obj.get_paginated_response(ser.data) #返回带上下页连接的数据
  35. return response
  36. # return Response(ser.data) #不含上下页链接

游标方式分页的本质是通过记住当前页面数据的最大、最小id,翻页时根据记录的最大或者最小id,查询下一页对应的数据,这样就不会出现每一次翻页都会重头遍历数据的情况,大大的提高了查询效率。缺点是无法直接跳转到某一页。

url路由器

我们在使用rest_framework时,url都是一个规定的格式,当我们有很多表时,意味着大量的复用一些代码,对于每一个模型表对应的url,只有两个地方不同,一个是路径的前缀,一个是对应的视图类。在rest_framework中也提供了一个url的分发,完美的解决了url的分发。

  1. from rest_framework import routers

rest_framework提供一个routers的py文件,这个文件中包含跟路由相关的类。

使用方式:在routers.py中有一个DefaultRouter类,先实例化一个这个类的对象,router=routers.DefaultRouter(),通过这个router对象,可以将对应的路径和视图类注册:router.register(r"路径前缀",对应的视图类),最后只需将url(r'^', include(router.urls)),这个url加入到urlpatterns中即可。

备注:rest_framework中为我们提供了四种形式的访问方式:

  1. books/
  2. books/1/
  3. books.json/
  4. books/?format=json            后两种不常用

响应器

rest_framework默认提供给我们两种响应器:

  1. DEFAULTS = {
  2. # Base API policies
  3. 'DEFAULT_RENDERER_CLASSES': (
  4. 'rest_framework.renderers.JSONRenderer',
  5. 'rest_framework.renderers.BrowsableAPIRenderer',
  6. ),

如果请求是浏览器,就用BrowsableAPIRenderer响应器返回一个页面,如果请求是非浏览器(比如Postman),就使用JSONRenderer响应一个json格式的数据。rest_framework提供这两个响应器是为了利于开发。

  我们可以在视图类中配置一个变量:renderer_classes = [JSONRenderer]

  1. from rest_framework.renderers import JSONRenderer

这样我们再使用浏览器发送请求是,响应的是一个json格式的字符串,而不是一个界面。

版本控制

  版本控制是由传入的客户端请求决定的,并且可能基于请求URL,或者基于请求头。

  restframework也提供了对应的版本控制。当使用版本控制时,request.version属性(字符串)与客户端请求的版本一致。 默认情况下,没有使用版本控制,request.version将会返回None,我们可以通过request.version的值进行判断和逻辑分发.

基于请求url:

  1. class APIView(View):
  2. # 版本控制的默认配置 可以在局部中定义versoning_class=的自定义配置
  3. versioning_class = api_settings.DEFAULT_VERSIONING_CLASS
  4.  
  5. def initial(self, request, *args, **kwargs):
  6. # 版本控制相关
  7. # Determine the API version, if versioning is in use.
  8. version, scheme = self.determine_version(request, *args, **kwargs)
  9. request.version, request.versioning_scheme = version, scheme

版本配置

全局配置

  1. 1. 添加配置
1
2
3
4
5
6
7
8
9
10
REST_FRAMEWORK = {
              
             ....
              
             'DEFAULT_VERSIONING_CLASS':'rest_framework.versioning.URLPathVersioning',
             'ALLOWED_VERSIONS':['v1','v2'], # 允许的版本
             'VERSION_PARAM':'version', # 参数
             'DEFAULT_VERSION':'v1', # 默认版本
             ....
      }
  1. 2. 设置路由
1
2
3
4
5
6
7
8
9
10
BeesCity/urls.py
             urlpatterns = [
                    #url(r'^admin/', admin.site.urls),
                    url(r'^api/(?P<version>\w+)/', include('api.urls')),
             ]
       
      api/urls.py
             urlpatterns = [
                    url(r'^course/$', course.CourseView.as_view()),
             ]
  1. 3. 传递版本信息
1
http://127.0.0.1:8000/api/v1/course/
  1. 4. 获取版本
1
request.version 获取版本 

局部配置

除非明确设置,否则DEFAULT_VERSIONING_CLASS值为None.此例中request.version将会始终返回None 
您还可以在一个单独的视图上设置版本控制方案。通常,您不需要这样做,因为在全局范围内使用一个版本控制方案更有意义。如果您确实需要这样做,请使用versioning_class属性。

1
2
3
4
from rest_framework.versioning import QueryParameterVersioning
 
class Course(APIView):
    versioning_class = QueryParameterVersioning

  这个时候可以用过url传参的方式来传递版本信息,如:

1
http://127.0.0.1:8000/api/course/?version=1

添加头信息控制版本

在API请求header中添加Accept字段。
Accept的作用是客户端指出响应可以接受的媒体类型
如Accept:application/json; version=v2
具体格式也可以参考下面。

Accept: application/vnd.xxxx[.version].param[+json]

例如Accept: application/vnd.demo.app-v2+json

  总结:小版本的更新可通过把版本号作为参数的方式或者通过accept字段标示版本号的方式判断,大的版本更新则通过URL上添加版本号控制

深入解析当下大热的前后端分离组件django-rest_framework系列四的更多相关文章

  1. 深入解析当下大热的前后端分离组件django-rest_framework系列一

    前言 Nodejs的逐渐成熟和日趋稳定,使得越来越多的公司开始尝试使用Nodejs来练一下手,尝一尝鲜.在传统的web应用开发中,大多数的程序员会将浏览器作为前后端的分界线.将浏览器中为用户进行页面展 ...

  2. 深入解析当下大热的前后端分离组件django-rest_framework系列二

    视图三部曲 一部曲 · 使用混合(mixins) 上一节的视图部分: from rest_framework.views import APIView from rest_framework.resp ...

  3. 深入解析当下大热的前后端分离组件django-rest_framework系列三

    三剑客之认证.权限与频率组件 认证组件 局部视图认证 在app01.service.auth.py: class Authentication(BaseAuthentication): def aut ...

  4. 海纳百川无所不容,Win10环境下使用Docker容器式部署前后端分离项目Django+Vue.js

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_179 随着现代化产品研发的不断推进,我们会发现,几乎每个产品线都会包含功能各异的服务,而且服务与服务之间存在也会存在着错综复杂的依 ...

  5. 《Spring Boot 入门及前后端分离项目实践》系列介绍

    课程计划 课程地址点这里 本课程是一个 Spring Boot 技术栈的实战类课程,课程共分为 3 个部分,前面两个部分为基础环境准备和相关概念介绍,第三个部分是 Spring Boot 项目实践开发 ...

  6. SpringBoot+Vue豆宝社区前后端分离项目手把手实战系列教程01---搭建前端工程

    豆宝社区项目实战教程简介 本项目实战教程配有免费视频教程,配套代码完全开源.手把手从零开始搭建一个目前应用最广泛的Springboot+Vue前后端分离多用户社区项目.本项目难度适中,为便于大家学习, ...

  7. SpringBoot+Vue豆宝社区前后端分离项目手把手实战系列教程02---创建后端工程

    本节代码开源地址 代码地址 项目运行截图 搭建后端工程 0.导入sql 在数据库导入 /* Navicat Premium Data Transfer Source Server : localhos ...

  8. Docker环境下的前后端分离项目部署与运维

    本教程将从零开始部署一个前后端分离的开源项目,利用docker虚拟机的容器技术,采用分布式集群部署,将项目转换成为高性能.高负载.高可用的部署方案.包括了MySQL集群.Redis集群.负载均衡.双机 ...

  9. 从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之十 || AOP面向切面编程浅解析:简单日志记录 + 服务切面缓存

    代码已上传Github+Gitee,文末有地址 上回<从壹开始前后端分离[ .NET Core2.0 Api + Vue 2.0 + AOP + 分布式]框架之九 || 依赖注入IoC学习 + ...

随机推荐

  1. 项目管理---git----快速使用git笔记(六)------本地开发与远程仓库的交互----常用git命令

    无论是我们自己把本地的项目新建了一个远程仓库 还是 从远程仓库获取到了 本地,现在我们都在本地有了一份项目代码,服务器上对应有项目代码的信息. 现在我们就开始进行交互操作了. 也就是说明一些在 正常开 ...

  2. React获取组件实例

    1. 直接new Component() 组件本身也是class,可以new,这样的组件实例意义不大 componentInstance = new Component(); 2. ReactDOM. ...

  3. Codeforces 864E Fire(背包DP)

    背包DP,决策的时候记一下 jc[i][j]=1 表示第i个物品容量为j的时候要选,输出方案的时候倒推就好了 #include<iostream> #include<cstdlib& ...

  4. NOIP2016Day2T3愤怒的小鸟(状压dp) O(2^n*n^2)再优化

    看这范围都知道是状压吧... 题目大意就不说了嘿嘿嘿 网上流传的写法复杂度大都是O(2^n*n^2),这个复杂度虽然官方数据可以过,但是在洛谷上会TLE[百度搜出来前几个博客的代码交上去都TLE了], ...

  5. 【状压DP】【P2831】【NOIP2016D2T3】愤怒的小鸟

    传送门 Description Kiana 最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于 $(0,0)$ 处,每次 Kiana 可以用它向第一象限发射一 ...

  6. bzoj 2654 tree 二分+kruskal

    tree Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 2739  Solved: 1126[Submit][Status][Discuss] Des ...

  7. template.js的使用心得

    template.js是一款JavaScript模板引擎,用来渲染页面的. 原理:提前将Html代码放进编写模板 <script id="tpl" type="te ...

  8. 单词转换成向量形式 word2vec

    word2vec(word to vector)是一个将单词转换成向量形式的工具.可以把对文本内容的处理简化为向量空间中的向量运算,计算出向量空间上的相似度,来表示文本语义上的相 似度.word2ve ...

  9. Centos下Mysql密码忘记解决办法

    1.修改MySQL的登录设置: # vim /etc/my.cnf 在[mysqld]的段中加上一句:skip-grant-tables 例如: [mysqld] datadir=/var/lib/m ...

  10. [uva11997]k个最小和

    一个k*k的矩阵,每行选取一个数相加则得到一个和,求最小的前k个和. k<=750 已知前m行最小的前k个和d[1]…d[k],则前m+1行最小的前k个和都必定是d[i](i<=k)+a[ ...