一、手动编写配置文件

# 默认配置
# conf-->global_setting.py
DEBUG = NoneTIME_ZONE = 'America/Chicago'USE_TZ = False# 用户配置
# usersetting-->setting.py
DEBUG = TrueTIME_ZONE = 'Asia/Shanghai'USE_TZ = FalseABC='123'
# conf-->__init__.py
from conf import global_setting
import os
import importlibclass MySetting():# dir:返回模块的属性列表def __init__(self):settings_module = os.environ.get('USER_SETTING')# 通过环境变量,获得用户配置的文件路径(字符串)# settings_module = 'usersetting.setting'# 循环获得默认配置的值for setting in dir(global_setting):if setting.isupper():setattr(self, setting, getattr(global_setting, setting))# 使用importlib.import_module()获得用户配置的路径mod = importlib.import_module(settings_module)# 循环获得用户配置的值,会覆盖默认配置for setting in dir(mod):if setting.isupper():setattr(self, setting, getattr(mod, setting))setting = MySetting()
# 运行文件
import osos.environ.setdefault('USER_SETTING', 'usersetting.setting')from conf import setting
print(setting.DEBUG)

二、分页器

1.普通分页

基本使用

# 普通分页
from rest_framework.pagination import PageNumberPaginationclass Books(APIView):def get(self, request):books = models.Book.objects.all()# 生成一个PageNumberPagination对象page = PageNumberPagination()# 第一个参数:要分页的数据,第二个参数request对象,第三个参数,当前视图对象# 在数据库中获取分页的数据page_list = page.paginate_queryset(books, request, self)ret = BooksSerializer(instance=page_list, many=True)print(ret.data)return Response(ret.data)# 这个也是返回Response对象,但是比基本的多了上一页,下一页,和总数据条数(了解即可)# return page.get_paginated_response(ret.data)
# setting.py
# 配置每页显示数
REST_FRAMEWORK = {# 每页显示两条'PAGE_SIZE': 2
}

配置属性

# 方法一:自定义分页类继承PageNumberPaginationclass MyPageNumberPagination(PageNumberPagination):# 每页显示的数据数,默认去setting里找page_size = 3# 配置GET里接收的key:value形式的key值,可以指定当前页# http://127.0.0.1:8000/books/?p=2# 默认为pagepage_query_param = 'p'# 可以通过URL的方式指定每页显示的数据数# http://127.0.0.1:8000/books/?page=2&size=1# 默认为sizepage_size_query_param='s'# 每页最多显示数据数max_page_size = 4class Books(APIView):def get(self, request):books = models.Book.objects.all()# 生成一个自定义的对象page = MyPageNumberPagination()page_list = page.paginate_queryset(books, request, self)ret = BooksSerializer(instance=page_list, many=True)print(ret.data)return Response(ret.data)
# 方式二:视图里设置属性
class Books(APIView):def get(self, request):books = models.Book.objects.all()page = PageNumberPagination()page.page_size = 3page.page_query_param = 'page'page.page_size_query_param = 'size'page.max_page_size = 4page_list = page.paginate_queryset(books, request, self)ret = BooksSerializer(instance=page_list, many=True)print(ret.data)return Response(ret.data)

2.偏移分页

基本使用

# 偏移分页
from rest_framework.pagination import LimitOffsetPaginationclass Books(APIView):def get(self, request):books = models.Book.objects.all()# 生成一个LimitOffsetPagination对象page = LimitOffsetPagination()# 第一个参数:要分页的数据,第二个参数request对象,第三个参数,当前视图对象# 在数据库中获取分页的数据page_list = page.paginate_queryset(books, request, self)ret = BooksSerializer(instance=page_list, many=True)print(ret.data)return Response(ret.data)# 这个也是返回Response对象,但是比基本的多了上一页,下一页,和总数据条数(了解即可)# return page.get_paginated_response(ret.data)
# setting.py
# 配置每页显示数
REST_FRAMEWORK = {# 每页显示两条'default_limit':2
}

配置属性

# 配置属性的两种方法与普通分页一样
# 每页显示的条数
default_limit = api_settings.PAGE_SIZE# 标杆值
# 配置GET里接收的key:value形式的key值,可以指定标杆值
# 一般和limit_query_param一起使用
# 默认为offset,可以自定义
offset_query_param = 'offset'# 可以通过URL的方式指定每页显示的数据数
# http://127.0.0.1:8000/books/?offset=4&limit=3
# 从第四条数据(不包括)开始取三条数据
# 如果写了limit=3,会覆盖default_limit的数据数
# 默认为limit,可以自定义
limit_query_param = 'limit'# 每页显示最大的条数
# 如果写了limit的值>max_limit的值,以max_limit为准
max_limit = None

3.加密分页

基本使用

# 加密分页
from rest_framework.pagination import CursorPaginationclass Books(APIView):def get(self, request):books = models.Book.objects.all()# 生成一个PageNumberPagination对象page = CursorPagination()# 先把数据按照ordering排序,再从数据库取出来page.ordering = 'id'page_list = page.paginate_queryset(books, request, self)ret = BooksSerializer(instance=page_list, many=True)return Response(ret.data)# page.get_paginated_response()会返回链接和总的数据数# return page.get_paginated_response(ret.data)
# setting.py
# 配置每页显示数
REST_FRAMEWORK = {# 每页显示两条'PAGE_SIZE': 2,
}

配置属性

# 配置属性的两种方法与普通分页一样'
# 每页显示的条数
page_size = api_settings.PAGE_SIZE# 在URL显示加密后的页码
# http://127.0.0.1:8000/books/?cursor=cD0y
# 默认为cursor,可以自定义
cursor_query_param = 'cursor# 数据按照ordering排序,默认是'-created'
ordering = '-created'# 每页最多显示数据数
max_page_size = 4

三、版本控制

基于restful规范,应当由版本之分,rest-framework给我们提供了一个

from rest_framework.versioning import QueryParameterVersioning,AcceptHeaderVersioning,NamespaceVersioning,URLPathVersioning# 基于url的get传参方式:
#  QueryParameterVersioning------>如:/users?version=v1# 基于url的正则方式:
#  URLPathVersioning------>/v1/users/# 基于 accept 请求头方式:
#  AcceptHeaderVersioning------>Accept: application/json; version=1.0# 基于主机名方法:
#  HostNameVersioning------>v1.example.com# 基于django路由系统的namespace:
#  NamespaceVersioning------>example.com/v1/users/

基本使用

# 路由
url(r'^(?P<version>[v1|v2|v3]+)/books/', views.Books.as_view()),
from rest_framework.versioning import URLPathVersioningclass Books(APIView):# 局部使用versioning_class = URLPathVersioningdef get(self, request,*args,**kwargs):books = models.Book.objects.all()# 获得版本号print(request.version)# URLPathVersioning对象print(request.versioning_scheme)ret = BooksSerializer(books, many=True)return Response(ret.data)#全局使用
REST_FRAMEWORK = {'DEFAULT_VERSIONING_CLASS':'rest_framework.versioning.URLPathVersioning','DEFAULT_VERSION': 'v1',            # 默认版本(从request对象里取不到,显示的默认值)'ALLOWED_VERSIONS': ['v1', 'v2'],   # 允许的版本'VERSION_PARAM': 'version'          # URL中获取值的key
}

反向解析

# url
url(r'^(?P<version>[v1|v2|v3]+)/books/', views.Books.as_view(),name='test'),# 反向生成URL
# 第一个参数是路由名,第二个是request
reverse_url = request.versioning_scheme.reverse('test', request=request)
print(reverse_url)
# http://127.0.0.1:8000/v1/books/

源码解析

# 第一步
# dispatch()
def dispatch(self, request, *args, **kwargs):........# 由此进入下一步self.initial(request, *args, **kwargs)........
# 第二步
# initial()
def initial(self, request, *args, **kwargs):........# 把determine_version方法的返回值解压赋值给version和scheme# 也就是version = 版本号# scheme = 版本类对象version, scheme = self.determine_version(request, *args, **kwargs)# 再把version和scheme分别赋值给requestrequest.version, request.versioning_scheme = version, scheme........
# 第三步
# self.determine_version()
def determine_version(self, request, *args, **kwargs):# 如果versioning_class is None,返回空元组if self.versioning_class is None:return (None, None)# 如果有,就加上()执行# 从视图里找,有:versioning_class = URLPathVersioning# scheme = URLPathVersioning()# 也就是说scheme是URLPathVersioning实例化后的对象scheme = self.versioning_class()# 返回元组(scheme.determine_version(request, *args, **kwargs),scheme)# scheme.determine_version(),是在URLPathVersioning里的方法return (scheme.determine_version(request, *args, **kwargs), scheme)
# 第四步
# URLPathVersioning ---> determine_version
def determine_version(self, request, *args, **kwargs):# version_param和default_version都会从setting里找# version_param='version'# default_version='v1'# 假设url: http://127.0.0.1:8000/v2/books/# 从参数里找url传进来的version,也就是v2,没有就默认值self.default_versionversion = kwargs.get(self.version_param, self.default_version)# is_allowed_version,从下往上找,都没有,在父类BaseVersioning里# 也就是说,如果返回True,就直接把接收到的version返回,false则抛异常if not self.is_allowed_version(version):raise exceptions.NotFound(self.invalid_version_message)return version# BaseVersioning ---> is_allowed_version()
def is_allowed_version(self, version):# 如果视图里没有,会从setting里找,还没有,就去默认里找,默认里是None,就返回True# 也就是说,如果setting里写了但为空,或者没写,就返回Trueif not self.allowed_versions:return True# 只要version为空并且version不在allowed_versions范围内# 或者version不等于默认值default_version并且version不在allowed_versions范围内# 就会返回falsereturn ((version is not None and version == self.default_version) or(version in self.allowed_versions))

转载于:https://www.cnblogs.com/xvchengqi/p/10139251.html

DAY102 - Rest Framework(七)- 手动编写配置文件、分页器和版本控制相关推荐

  1. 【Microsoft Azure 的1024种玩法】七十二.使用NodeJS手动编写调用Azure Cognitive Services Translator API代码获取其支持翻译的语言集

    [简介] Azure Cognitive Services Translato 是一种基于云的神经网络机器翻译服务,同时也是 REST API 的 Azure 认知服务系列的一部分. 本篇文章将会主要 ...

  2. NATS_08:NATS客户端Go语言手动编写

    NATS客户端     一个NATS客户端是基于NATS服务端来说既可以是一个生产数据的也可以是消费数据的.生产数据的叫生产者英文为 publishers,消费数据的叫消费者英文为 subscribe ...

  3. 用 .Net Framework 4.0 制作的安装程序来安装 .Net Framework 4.0 编写的程序

    文章题目看起来有点绕,解释一下,假如你基于框架写了一个程序,想装到客户机上,但是客户机上可能并没有安装框架,因此你的程序需要预先将框架安装在目标机上,然后再执行一些安装程序的标准功能,如创建快捷方式. ...

  4. cmake学习笔记(七)编写自己的xxxConfig.cmake

    cmake学习笔记(七)编写自己的xxxConfig.cmake 1. onnxruntimeConfig.cmake 2. 进阶版onnxruntimeConfig.cmake 1. onnxrun ...

  5. iOS 11开发教程(七)编写第一个iOS11代码Hello,World

    iOS 11开发教程(七)编写第一个iOS11代码Hello,World 代码就是用来实现某一特定的功能,而用计算机语言编写的命令序列的集合.现在就来通过代码在文本框中实现显示"Hello, ...

  6. [Cocoa]深入浅出 Cocoa 之 Core Data(2)- 手动编写代码

    深入浅出 Cocoa 之 Core Data(2)- 代码示例 罗朝辉(http://blog.csdn.net/kesalin) CC 许可,转载请注明出处 前面 详细讲解了 Core Data 的 ...

  7. 如何编写配置文件 JAVA_SpringBoot 如何编写配置文件

    我们经常在项目开放中需要进行很多配置, 那么这些配置基本上都是动态的, 如果我直接写在代码中, 修改起来很麻烦, 如果该配置在多处进行引用啦, 你估计会杀了写代码的人. 那么我们在使用SpringBo ...

  8. [Cocoa]深入浅出Cocoa之Core Data(2)- 手动编写代码

    深入浅出Cocoa之Core Data(2)- 手动编写代码 罗朝辉 (http://www.cnblogs.com/kesalin/) 本文遵循"署名-非商业用途-保持一致"创作 ...

  9. 从配置文件(*.config)读到内存中,手动修改配置文件后,内存中数据改变问题.

    某些情况,我们把数据信息存储在*.xml或*.config文件中,存储在*.config中会比较安全,发布的程序,浏览器不会打开*.config文件,但是*.xml会在浏览器中呈现. 使用.confi ...

最新文章

  1. 047_Unicode对照表十三
  2. Linux服务器文件描述符最大值修改
  3. VC获取其他进程ListCtrl内容
  4. python装饰器是什么意思_这个python 装饰器代码是什么意思?
  5. WCF系列(二) -- 使用配置文件构建和使用WCF服务
  6. mysql添加外键约束失败cannot add foreign key constraint
  7. 图层样式混合选项_图标设计,用PS的图层样式制作逼真的玉石图标
  8. 树莓派智能小车python_人工智能-树莓派小车(1)——DuerOS语音唤醒
  9. h5打开app_移动端产品比较分析:APP、小程序、H5
  10. MD1——2 Corner
  11. 苹果电脑如何正确断网?macOS操作系统断网方法
  12. 整理15款实用javascript富文本编辑器 转自136go
  13. cs229 学习笔记四 学习理论
  14. vue项目中引用阿里云图标库
  15. CEO陈睿多措施并举,为B站的创新发展护航
  16. 常见功能测试设计方法
  17. 【DSP学习笔记】定点DSP小数乘加计算
  18. org.apache.shiro.session.ExpiredSessionException: Session with id异常排查
  19. 精讲精练_参悟Android核心技术-张晓飞-专题视频课程
  20. AndroidStudio运行app,会装上多个app

热门文章

  1. iconfont字体图标的使用方法
  2. qtreewidget点击空白处时取消以选项_手机APP自动续费,我们要如何取消?
  3. 万紫千红总是春的上一句是什么,万紫千红总是春全诗赏析
  4. 直播的一般流程是什么?
  5. 现在资本进入社区团购,大搞补贴战,算不算涉嫌扰乱市场,垄断?
  6. 富文本编辑器KindEditor在前端JS的应用
  7. beanfactory的实现类_ApplicationContext和BeanFactory的区别
  8. azure 入门_Azure Databricks入门指南
  9. sphinx 入门_Sphinx搜索引擎入门
  10. tde数据库加密_如何在TDE加密的数据库上配置SQL Server镜像