目的: 可以给视图集添加额外的动作(方法)
操作流程:
1, 子路由
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^books/$',views.BookInfoModelViewSet.as_view({"get":"list","post":"create"})),
url(r'^books/(?P\d+)/$' ,views.BookInfoModelViewSet.as_view({"get":"retrieve","put":"update","delete":"destory"})),
url(r'^books/bread/$',views.BookInfoModelViewSet.as_view({"get":"bread_book"})),
]
2, 类视图
from django.shortcuts import render
from rest_framework.viewsets import ModelViewSet
from booktest.models import BookInfo
from booktest.serializers import BookInfoModelSerializer
from rest_framework.response import Response
#1,视图集
class BookInfoModelViewSet(ModelViewSet):
queryset = BookInfo.objects.all()
serializer_class = BookInfoModelSerializer
#1,获取阅读量大于20的书籍
def bread_book(self,request):
#1,获取指定书籍
books = BookInfo.objects.filter(bread__gt=20)
#2,创建序列化器对象
serializer = self.get_serializer(instance=books,many=True)
#3,返回响应
return Response(serializer.data)
#2,修改书籍编号为1的, 阅读量为99
3, 序列化器
from rest_framework import serializers
from booktest.models import BookInfo
#1,模型类序列化器
class BookInfoModelSerializer(serializers.ModelSerializer):
class Meta:
model = BookInfo
fields = "__all__"
目的: 可以编写额外动作添加参数, 并且更新局部信息
操作流程:
1, 子路由
url(r'^books/bread/(?P\d+)/$' ,
views.BookInfoModelViewSet.as_view({"put":"update_book_bread"})),
2, 类视图
class BookInfoModelViewSet(ModelViewSet):
...
#2,修改书籍编号为1的, 阅读量为99
def update_book_bread(self,request,pk):
#1,获取参数
book = self.get_object()
data = request.data
#2,创建序列化器,partial=True可以局部更新
serializer = self.get_serializer(instance=book,data=data,partial=True)
#3,校验,入库
serializer.is_valid(raise_exception=True)
serializer.save()
#4,返回响应
return Response(serializer.data,status=201)
目的: 可以通过DefaultRouter和SimpleRouter两个类来自动生成路由
DefautRouter生成路由格式:
特点: 共有三对路由
[
<RegexURLPattern haha-list ^books/$>,
<RegexURLPattern haha-list ^books\.(?P<format>[a-z0-9]+)/?$>,
<RegexURLPattern haha-detail ^books/(?P<pk>[^/.]+)/$>,
<RegexURLPattern haha-detail ^books/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$>,
<RegexURLPattern api-root ^$>,
<RegexURLPattern api-root ^\.(?P<format>[a-z0-9]+)/?$>
]
SimpleRouter生成路由格式:
特点: 生成两个路由
[
<RegexURLPattern haha-list ^books/$>,
<RegexURLPattern haha-detail ^books/(?P<pk>[^/.]+)/$>
]
操作流程:
1, 子路由
from rest_framework.routers import SimpleRouter,DefaultRouter
#1,创建路由对象
router = SimpleRouter()
#2,注册视图集
router.register('books',views.BookInfoModelViewSet,base_name="haha")
urlpatterns += router.urls
#3,输出结果
print(urlpatterns)
注意点:
目的: 可以通过action装饰方法, 自动生成路由
操作流程:
from rest_framework.decorators import action
#1,视图集
class BookInfoModelViewSet(ModelViewSet):
...
#1,获取阅读量大于20的书籍
@action(methods=['GET'],detail=False) #生成路由规则: 前缀/方法名/
def bread_book(self,request):
...
#2,修改书籍编号为1的, 阅读量为99
@action(methods=["PUT"],detail=True) #生成路由规则: 前缀/{pk}/方法名/
def update_book_bread(self,request,pk):
...
目的: 可以参考官方文档, 配置认证内容
操作流程:
1, 全局配置(setteings.py)
# DRF配置信息
REST_FRAMEWORK = {
#1,全局认证
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.BasicAuthentication', #此身份验证方案使用HTTP基本身份验证,用于测试使用
'rest_framework.authentication.SessionAuthentication', #自己服务器认证用户
]
}
2, 局部配置(views.py)
#1,视图集
class BookInfoModelViewSet(ModelViewSet):
...
#1,局部认证
authentication_classes = [SessionAuthentication]
注意点:
目的: 可以参考官方文档, 配置权限内容
操作流程:
1, 全局权限配置(settings.py)
REST_FRAMEWORK = {
#1,全局认证
...
#2,全局权限
'DEFAULT_PERMISSION_CLASSES': [
# 'rest_framework.permissions.IsAuthenticated', #普通用户
# 'rest_framework.permissions.AllowAny', #所有用户
'rest_framework.permissions.IsAdminUser', #管理员户
]
}
2, 局部权限配置(views.py)
#1,视图集
class BookInfoModelViewSet(ModelViewSet):
...
#1,局部认证
...
#2,局部权限
# permission_classes = [AllowAny]
目的: 可以通过配置, 限制不同用户的访问次数
操作流程:
1, 全局配置
# DRF配置信息
REST_FRAMEWORK = {
#1,全局认证
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.BasicAuthentication', #此身份验证方案使用HTTP基本身份验证,用于测试使用
'rest_framework.authentication.SessionAuthentication', #自己服务器认证用户
],
#2,全局权限
# 'DEFAULT_PERMISSION_CLASSES': [
# # 'rest_framework.permissions.IsAuthenticated', #普通用户
# # 'rest_framework.permissions.AllowAny', #所有用户
# 'rest_framework.permissions.IsAdminUser', #管理员户
# ],
#3,全局限流
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.AnonRateThrottle', #匿名用户
'rest_framework.throttling.UserRateThrottle' # 认证用户
],
'DEFAULT_THROTTLE_RATES': {
'anon': '2/minute',
'user': '3/minute'
}
}
2, 局部配置
#1,视图集
class BookInfoModelViewSet(ModelViewSet):
queryset = BookInfo.objects.all()
serializer_class = BookInfoModelSerializer
#1,局部认证
# authentication_classes = [SessionAuthentication]
#2,局部权限
# permission_classes = [AllowAny]
#3,局部限流
throttle_classes = [AnonRateThrottle]
目的: 可以定义可选限流, 用在不同的类视图中
操作流程:
1, 全局定义
# DRF配置信息
REST_FRAMEWORK = {
...
#4,可选限流
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.ScopedRateThrottle',
],
'DEFAULT_THROTTLE_RATES': {
'downloads': '3/minute',
'uploads': '5/minute'
}
}
2, 局部使用
class TestView(APIView):
throttle_scope = "uploads"
def get(self,request):
return Response("testing....")
目的: 可以参考文档, 设置分页返回
操作流程:
1, 全局配置
REST_FRAMEWORK = {
...
#5,全局分页
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
'PAGE_SIZE': 2
}
2, 局部配置
class BookInfoModelViewSet(ModelViewSet):
...
#5,局部分页
# pagination_class = LimitOffsetPagination # ?limit=100 或者 ?offset=400&limit=100
pagination_class = PageNumberPagination # ?page=4
目的: 可以自定义类, 实现指定分页大小效果
操作流程:
1, 类视图
#自定义分页对象
class MyPageNumberPagination(PageNumberPagination):
#1,默认的大小
page_size = 3
#2,前端可以指定页面大小
page_size_query_param = 'page_size'
#3,页面的最大大小
max_page_size = 5
#1,视图集
class BookInfoModelViewSet(ModelViewSet):
...
#6,自定义分页对象
pagination_class = MyPageNumberPagination # ?page=4 或者 ?page=4&page_size=100
目的: 可以根据文档配置,进行过滤数据获取
操作流程:
1, 安装扩展django-filters
2, 注册子应用
INSTALLED_APPS = [
...
'django_filters',
]
3, 全局配置
REST_FRAMEWORK = {
...
'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend']
}
4, 全局配置(views.py)
class BookInfoModelViewSet(ModelViewSet):
....
#7,局部过滤
filter_backends = [DjangoFilterBackend]
filterset_fields = ['id', 'btitle',"is_delete"]
目的: 可以参考文档, 使用指定的字段进行排序
操作流程:
1, 类视图
class BookInfoModelViewSet(ModelViewSet):
....
#8,局部排序
filter_backends = [filters.OrderingFilter] # 导包路径: from rest_framework import filters
ordering_fields = ['id', 'btitle','bread'] #查询格式: ?ordering=-bread,id
目的: 可以参考文档, 处理程序中的异常信息
操作流程:
1, 定义自定义处理方法(booktest/my_exception.py)
from rest_framework.views import exception_handler
from rest_framework.response import Response
from django.db import DatabaseError
def custom_exception_handler(exc, context):
#1,调用系统方法,处理了APIException的异常,或者其子类异常
response = exception_handler(exc, context)
#2,判断response是否有值
if response is not None:
response.data['status_code'] = response.status_code
else:
if isinstance(exc, DatabaseError):
response = Response("数据库大出血")
else:
response = Response("其他异常!")
return response
2, 全局配置(settings.py)
REST_FRAMEWORK = {
...
'EXCEPTION_HANDLER': 'booktest.my_exception.custom_exception_handler'
}
3, 测试(views.py)
class TestView(APIView):
# throttle_scope = "uploads"
def get(self,request):
# raise DatabaseError("DatabaseError!!!")
raise Exception("报错了!!!")
# raise APIException("APIException!!!")
# raise ValidationError("ValidationError!!!")
return Response("testing....")
目的: 可以参考文档, 配置后端数据的入口文档
操作流程:
1,安装扩展
2, 根路由
url(**r'^docs/'**, include_docs_urls(title=**'我的API文档'**))
3, 修改字段说明信息
btitle = models.CharField(max_length=20, verbose_name=**'名称'**,help_text=**"书籍标题"**)
序列化器
#1,模型类序列化器
class BookInfoModelSerializer(serializers.ModelSerializer):
class Meta:
...
extra_kwargs = {
'bread':{
'help_text':"书籍阅读量"
}
}
目的: 知道如何定义全局组件,并进行使用
操作流程:
1,组件定义
<script>
// 1,定义全局组件
Vue.component(
'global_component',
{
template:"迪丽热巴
"
}
)
// 2,创建vue对象
var vm = new Vue({
el:"#app"
})
</script>
2, 组件使用
<div id="app">
<global_component>global_component>
<global_component>global_component>
div>
目的: 知道如何定义局部组件,并进行使用
操作流程:
1,定义局部组件
<script>
//1,定义局部组件
var part_component = {
template:"古力娜扎
"
}
//2,创建vue对象, 注册局部组件
var vm = new Vue({
el:"#app",
components:{
part1:part_component,
part2:{
template:"马尔扎哈
"
}
}
})
</script>
2,使用局部组件
<div id="app">
<part1>part1>
<part2>part2>
div>
目的: 知道如何在全局组件中嵌套局部组件,并进行使用
操作流程:
1, 组件的嵌套定义
<script>
// 1,定义局部组件
var part1 = {
template:" 大头儿子 "
}
var part2 = {
template:" 围裙妈妈 "
}
// 2,全局组件
Vue.component(
'global_component',
{
template:" 小头巴巴, , ",
components:{part1,part2}
}
)
// 3,创建vue对象
var vm = new Vue({
el:"#app"
})
</script>
2, 使用
<div id="app">
<!-- 1,使用组件 -->
<global_component></global_component>
</div>
目的: 可以在全局组件中定义data,并获取数据
操作流程:
1,全局组件定义data
<script>
// 1,全局组件
Vue.component(
'global_component',
{
template:"迪丽热巴, {{name}} ,{{age}}
",
data:function(){
return {
name:"刷我滴卡",
age:13
}
}
}
)
// 2,vm对象
var vm = new Vue({
el:"#app",
data: {
}
})
</script>
2,使用
<div id="app">
<global_component>global_component>
div>
目的:知道如何去改写, 分页对象的返回数据
操作流程:
1, 类视图(views.py)
#自定义分页对象
class MyPageNumberPagination(PageNumberPagination):
...
def get_paginated_response(self, data):
return Response(OrderedDict([
('haha', 'zhangsan'),
('count', self.page.paginator.count),
('next', self.get_next_link()),
('previous', self.get_previous_link()),
('results', data)
]))