rest_framework框架
rest_framework框架的认识
它是基于Django的,帮助我们快速开发符合RESTful规范的接口框架。
一 路由
可以通过路由as_view()传参 根据请求方式的不同执行对应不同的方法
在routers模块下 封装了很多关于路由的方法 , 最基础的BaseRouter类,给我提供自定制的接口。
下面这个方法给我们提供了自动生成两条带参数的url
from rest_framework import routers
from django.conf.urls import url, include
from course.models import Course
from course.views import CourseView routers = routers.DefaultRouter()
routers.register('Course', CourseView) urlpatterns = [
url(r'^', include(routers.urls)), ]
二 视图
帮助开发者提供了一些类,并在类中提供了多种方法供我们使用,下图是提供的主要的类以及继承关系。
提供其他一些视图函数类,可以去源码里看。
三 版本控制
下面以URL上控制版本为例
1、添加配置
REST_FRAMEWORK = {
# 默认使用的版本控制类
'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning',
# 允许的版本
'ALLOWED_VERSIONS': ['v1', 'v2'],
# 版本使用的参数名称
'VERSION_PARAM': 'version',
# 默认使用的版本
'DEFAULT_VERSION': 'v1',
}
2、设置路由
urlpatterns = [
#url(r'^admin/', admin.site.urls),
url(r'^api/(?P<version>\w+)/', include('api.urls')),
]
3、获取版本
request.version
四 认证
rest_framework给我们提供了认证的接口,由BaseAuthentication类提供接口,也有一些封装好的认证类(请走入源码....)
接口函数 authticate 认证成功返回一元组(user,token)分别赋值给request.user 和 request.auth
下面是一个简单的认证示例
class Auth(BaseAuthentication):
def authenticate(self, request):
token = request.query_params.get('token')
obj = models.Token.objects.filter(token=token).first()
if not obj:
raise AuthenticationFailed({'code': 1001, 'error': '认证失败'})
return (obj.user.username, obj)
我们的认证类可以放在局部视图函数,也可以配置为全局认证。
# 局部视图函数认证
class MyView(APIView):
authentication_classes = [Auth]
pass
# 全局配置 在settings.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [Auth],
}
五 权限
由BasePermission类给我提供接口 接口函数为 has_permission 以及 has_object_permission
有权限返回True 没有则返回False,默认的权限类为下图。
# 允许任何人访问
class AllowAny(BasePermission):
"""
Allow any access.
This isn't strictly required, since you could use an empty
permission_classes list, but it's useful because it makes the intention
more explicit.
""" def has_permission(self, request, view):
return True
接口类为下图
class BasePermission(object):
"""
A base class from which all permission classes should inherit.
""" def has_permission(self, request, view):
"""
Return `True` if permission is granted, `False` otherwise.
"""
# 这里写我们的权限逻辑
return True def has_object_permission(self, request, view, obj):
"""
Return `True` if permission is granted, `False` otherwise.
"""
return True
还封装了一些权限类,只允许admin用户访问的权限,只给认证的用户权限等等,请走源码........
六 频率
基础的BaseThrottle类提供接口 接口函数为 allow_request,如果返回False则走wait
SimpleRateThrottle类给我们提供了get_cache_key接口,继承这个类要写rate(num_request, duration)多长时间内访问次数
实现原理如下代码:
class SimpleRateThrottle(BaseThrottle):
def allow_request(self, request, view):
if self.rate is None:
return True self.key = self.get_cache_key(request, view)
if self.key is None:
return True self.history = self.cache.get(self.key, [])
self.now = self.timer() # 原理的实现逻辑
while self.history and self.history[-1] <= self.now -self.duration:
self.history.pop()
if len(self.history) >= self.num_requests:
return self.throttle_failure()
return self.throttle_success()
这里就放这些~~具体~请大家走入源码.......
七 序列化
对queryset序列化以及对请求数据格式验证。
通常继承两个类 Serializer 以及 ModelSerializer
Serializer 序列化的每个字段都要自己写 ModelSerializer 会根据数据库表渲染所有字段
注意sourse 以及 钩子函数的应用 代码如下:
class CourseDetailModelSerializers(serializers.ModelSerializer):
title = serializers.CharField(source='course.name')
img = serializers.ImageField(source='course.course_img')
level = serializers.CharField(source='course.get_level_display')
recommends = serializers.SerializerMethodField()
chapters = serializers.SerializerMethodField() def get_recommends(self, obj):
queryset = obj.recommend_courses.all()
return [{'id': row.id, 'title': row.name} for row in queryset] def get_chapters(self, obj):
queryset = obj.course.course_chapters.all()
return [{'id': row.id, 'name': row.name} for row in queryset] class Meta:
model = CourseDetail
fields = ['course', 'title', 'img', 'level', 'why_study', 'chapters', 'recommends']
八 分页
对从数据库中获取到的数据进行分页处理 SQL --> limit offset
- 根据页码:http://www.myclass.com/api/v1/student/?page=1&size=10
- 根据索引:http://www.myclass.com/api/v1/student/?offset=60&limit=10
- 根据游标:http://www.myclass.com/api/v1/student/?page=erd8
页码越大速度越慢,为什么怎么解决?
- 原因:页码越大向后需要扫描的行数越多,因为每次都是从0开始扫描
- 解决:
- 限制当前显示的页数
- 记录当前页面数据ID的最大值和最小值,再次分页时,根据ID进行筛选,在分页
rest_framework 分页的配置
- 全局分页配置
# settings.py
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
'PAGE_SIZE': 100
}
- 修改分页风格
class MyPagination(PageNumberPagination):
page_size = 100
page_size_query_param = 'page_size'
max_page_size = 1000 # 然后在视图中使用.pagination_class属性调用该自定义类
class MyView(generics.ListAPIView):
queryset = Billing.objects.all()
serializer_class = BillingRecordsSerializer
pagination_class = MyPagination # 或者是在settings.py中修改DEFAULT_PAGINATION_CLASS REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'apps.core.pagination.MyPagination'
}
rest_framework给我提供的API
1、 PageNumberPagination
GET https://api.example.org/accounts/?page=4
响应对象
HTTP 200 OK
{
"count": 1023
"next": "https://api.example.org/accounts/?page=5",
"previous": "https://api.example.org/accounts/?page=3",
"results": [
…
]
}
配置属性
- page_size 每页显示对象的数量 如果设置了就重写PAGE_SIZE
- page_query_param 页面查询参数 指示分页空间的查询参数的名字
- page_size_query_param 允许客户端根据每个请求设置页面大小 一般都为None
- max_page_size 设置了page_size_query_param 才有意义 客户端请求页面中显示最大数量
- last_page_strings 储存page_query_param参数请求过的值列表或元组
2、LImitOffsetPagination
路由配置以及返回类型
GET https://api.example.org/accounts/?limit=100&offset=400 HTTP 200 OK
{
"count": 1023
"next": "https://api.example.org/accounts/?limit=100&offset=500",
"previous": "https://api.example.org/accounts/?limit=100&offset=300",
"results": [
…
]
}
配置参数
- page_size 每页显示对象的数量 如果设置了就重写PAGE_SIZE
- default_limit: 如果客户端没有提供,则默认使用与PAGE_SIZE值一样。
- limit_query_param:表示限制查询参数的名字,默认为’limit’
- offset_query_param:表示偏移参数的名字, 默认为’offset’
- max_limit:允许页面中显示的最大数量,默认为None
3、CursorPagination
- 基于游标的分页显示了一个不透明的“cursor”指示器,客户端可以使用它来浏览结果集。
- 这种分页方式只允许用户向前或向后进行查询。并且不允许客户端导航到任意位置。
- 基于游标的分页方式比较复杂,它要求结果集给出一个固定的顺序,并且不允许客户端任意的对结果集进行索引
全局配置如下
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.CursorPagination',
'PAGE_SIZE': 100
}
配置参数:
- page_size:显示的最大条数
- cursor_query_param: 游标查询参数名,默认为’cursor’
- ordering: 排序字段名的列表或者元组,例如ordering = ‘slug’,默认为-created
4、自定义分页
- 继承pagination.BasePagination
- 重写paginate_queryset(self, queryset, request, view=None)方法 ,
初始化queryset对象,设置pagination实例 返回一个包含用户请求内容的可迭代对象 形成分页对象
- 重写get_paginated_response(self, data)方法
序列化请求页中所包含的对象,返回一个Response对象
class CustomPagination(pagination.PageNumberPagination):
def get_paginated_response(self, data):
return Response({
'links': {
'next': self.get_next_link(),
'previous': self.get_previous_link()
},
'count': self.page.paginator.count,
'results': data
}) # 设置自定义分页、
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'my_project.apps.core.pagination.CustomPagination',
'PAGE_SIZE': 100
}
九 解析器
默认的三个解析器
- JsonParser Json数据解析器
- FormParser 和 MultiPartParser 一般同时使用
Both request.data
will be populated with a QueryDict
. 官方文档的解释
DEFAULTS = {
# rest_framework settings.py
'DEFAULT_PARSER_CLASSES': (
'rest_framework.parsers.JSONParser',
'rest_framework.parsers.FormParser',
'rest_framework.parsers.MultiPartParser'
),
}
十 渲染器
默认的两个渲染器,一个是Json的,一个是用浏览器访问rest_framework自带的模板的
DEFAULTS = {
# rest_framework setting.py
'DEFAULT_RENDERER_CLASSES': (
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
),
}
rest_framework框架的更多相关文章
- rest_framework框架之认证功能的使用和源码实现流程分析
rest_framework框架之认证的使用和源码实现流程分析 一.认证功能的源码流程 创建视图函数 Note 创建视图函数后,前端发起请求,url分配路由,执行视图类,视图类中执行对应方法必须经过d ...
- rest_framework框架下的Django声明和生命周期
rest_framework框架下的Django声明和生命周期 Django声明周期(request) 客户端发起请求 请求经过wsgi wsgi: 是一个协议----web服务网关接口,即在web服 ...
- rest_framework框架的认识
它是基于Django的,帮助我们快速开发符合RESTful规范的接口框架. 一 路由 可以通过路由as_view()传参 根据请求方式的不同执行对应不同的方法 在routers模块下 封装了很多关于 ...
- django rest_framework 框架的使用
django 的中间件 csrf Require a present and correct csrfmiddlewaretoken for POST requests that have a CSR ...
- Django之REST_framework 框架基本组件使用
快速实例 快速实例: 点击查看官方文档 阅读推荐:点击查看 序列化 创建一个序列化类 简单使用 开发我们的Web API的第一件事是为我们的Web API提供一种将代码片段实例序列化和反序列化为诸如j ...
- rest_framework框架——版本控制组件
API版本控制可以用来在不同的客户端使用不同的行为.REST框架提供了大量不同的版本设计. 版本控制是由传入的客户端请求决定的,并且可基于请求URL,或者基于请求头. rest_framework 当 ...
- rest_framework框架的基本组件
快速实例 Quickstart 序列化 创建一个序列化类 简单使用 开发我们的Web API的第一件事是为我们的Web API提供一种将代码片段实例序列化和反序列化为诸如json之类的表示形式的方式. ...
- django的rest_framework框架源码剖析
在看源码之前先了解一下什么是rest,restful api. 什么是rest 可以总结为一句话:REST是所有Web应用都应该遵守的架构设计指导原则. REST是Representational S ...
- Python之Django rest_Framework框架源码分析
#!/usr/bin/env python # -*- coding:utf-8 -*- from rest_framework.views import APIView from rest_fram ...
随机推荐
- Markdown 语法手册 - 完整版(上)
https://blog.csdn.net/witnessai1/article/details/52551362 1. 斜体和粗体 代码: *斜体*或_斜体_ **粗体** ***加粗斜体*** ~ ...
- javascript数据类型的判断
最近看到了很多关于数据类型判断的方法,总结了下 一.javascript的数据类型 js数据分为两种类型:原始数据类型和引用数据类型.原始数据类型有:string.number.boolean.und ...
- 使用Let’s Encrypt生成免费的SSL证书
SSL(安全套接层,Secure Sockets Layer),及其继任者 TLS (传输层安全,Transport Layer Security)是为网络通信提供安全及数据完整性的一种安全协议.TL ...
- java中常用jar包
commons-io.jar:可以看成是java.io的扩展,用来帮助进行IO功能开发.它包含三个主要的领域:Utilityclasses-提供一些静态方法来完成公共任务.Filters-提供文件过滤 ...
- 基于Centos搭建Python Web 环境搭建教程
CentOS 7.2 64 位操作系统 安装 setuptools 工具 安装 因为之后我们需要安装 Django ,而 Django 需要用这个工具,所以我们需要先安装 setuptools 工具. ...
- asp.net 逻辑操作符与(&&),或(||),非(!)
逻辑操作符与(&&),或(||),非(!)能根据参数的关系返回布尔值 public class bool{ public static void main(string [] args ...
- appium 获取android 粘贴板上的内容
appium 新版本增加了获取粘贴板的内容.如果使用appium旧版本,获取粘贴板的内容不是那么容易的,甚至百度谷歌各种搜,都无法找到合适的解决方法.新版本获取android 粘贴板内容就显得很容易了 ...
- 解决zabbix的中文乱码
CentOS7.1 x64上下载了zabbix官方的rpm包,导入后使用yum安装了zabbix 3.2.6,但是启动zabbix server的时候报了个段错误的错,谷歌了一会儿,发现段错误不止一次 ...
- 0x02 Spring Cloud 学习文档
每个Spring项目都有自己的; 它详细解释了如何使用项目功能以及使用它们可以实现的功能. Spring Cloud 版本 参考文档 API文档 Finchley SR2 CURRENT GA Ref ...
- (转)PyCharm报错:“No R interpreter defined: Many R……”——解决办法
报错截图: 下载安装链接:The Comprehensive R Archive Network