在Django学习[60]中的views.py的类视图中,使用继承了viewsets.ModelViewSet
Viewsets
ViewSetMixin
class ViewSetMixin:
"""
This is the magic.
Overrides `.as_view()` so that it takes an `actions` keyword that performs
the binding of HTTP methods to actions on the Resource.
For example, to create a concrete view binding the 'GET' and 'POST' methods
to the 'list' and 'create' actions...
view = MyViewSet.as_view({'get': 'list', 'post': 'create'})
"""
@classonlymethod
def as_view(cls, actions=None, **initkwargs):
"""
Because of the way class based views create a closure around the
instantiated view, we need to totally reimplement `.as_view`,
and slightly modify the view function that is created and returned.
"""
# The name and description initkwargs may be explicitly overridden for
# certain route configurations. eg, names of extra actions.
cls.name = None
cls.description = None
# The suffix initkwarg is reserved for displaying the viewset type.
# This initkwarg should have no effect if the name is provided.
# eg. 'List' or 'Instance'.
cls.suffix = None
# The detail initkwarg is reserved for introspecting the viewset type.
cls.detail = None
# Setting a basename allows a view to reverse its action urls. This
# value is provided by the router through the initkwargs.
cls.basename = None
# actions must not be empty
if not actions:
raise TypeError("The `actions` argument must be provided when "
"calling `.as_view()` on a ViewSet. For example "
"`.as_view({'get': 'list'})`")
# sanitize keyword arguments
for key in initkwargs:
if key in cls.http_method_names:
raise TypeError("You tried to pass in the %s method name as a "
"keyword argument to %s(). Don't do that."
% (key, cls.__name__))
if not hasattr(cls, key):
raise TypeError("%s() received an invalid keyword %r" % (
cls.__name__, key))
# name and suffix are mutually exclusive
if 'name' in initkwargs and 'suffix' in initkwargs:
raise TypeError("%s() received both `name` and `suffix`, which are "
"mutually exclusive arguments." % (cls.__name__))
def view(request, *args, **kwargs):
self = cls(**initkwargs)
if 'get' in actions and 'head' not in actions:
actions['head'] = actions['get']
# We also store the mapping of request methods to actions,
# so that we can later set the action attribute.
# eg. `self.action = 'list'` on an incoming GET request.
self.action_map = actions
# Bind methods to actions
# This is the bit that's different to a standard view
for method, action in actions.items():
handler = getattr(self, action)
setattr(self, method, handler)
self.request = request
self.args = args
self.kwargs = kwargs
# And continue as usual
return self.dispatch(request, *args, **kwargs)
# take name and docstring from class
update_wrapper(view, cls, updated=())
# and possible attributes set by decorators
# like csrf_exempt from dispatch
update_wrapper(view, cls.dispatch, assigned=())
# We need to set these on the view function, so that breadcrumb
# generation can pick out these bits of information from a
# resolved URL.
view.cls = cls
view.initkwargs = initkwargs
view.actions = actions
return csrf_exempt(view)
第15行重写了as_view,添加了一些过滤和反向解析
GenericViewSet
class GenericViewSet(ViewSetMixin, generics.GenericAPIView):
"""
The GenericViewSet class does not provide any actions by default,
but does include the base set of generic view behavior, such as
the `get_object` and `get_queryset` methods.
"""
pass
继承自generics.GenericAPIView
和 ViewSetMixin
generics.GenericAPIView
在上一篇已经介绍过。
ViewSet
class ViewSet(ViewSetMixin, views.APIView):
"""
The base ViewSet class does not provide any actions by default.
"""
pass
默认什么都不支持,需要自己手动实现
ReadOnlyModelViewSet
只读的模型的视图集合
class ReadOnlyModelViewSet(mixins.RetrieveModelMixin,
mixins.ListModelMixin,
GenericViewSet):
"""
A viewset that provides default `list()` and `retrieve()` actions.
"""
pass
继承自:
- mixins.RetrieveModelMixin
- mixins.ListModelMixin
- GenericViewSet
- 只能获取数据,所以只读
ModelViewSet
直接封装对象的所有操作
class ModelViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet):
"""
A viewset that provides default `create()`, `retrieve()`, `update()`,
`partial_update()`, `destroy()` and `list()` actions.
"""
pass
继承自:
- mixins.CreateModelMixin
- mixins.RetrieveModelMixin
- mixins.UpdateModelMixin
- mixins.DestroyModelMixin
- mixins.ListModelMixin
- GenericViewSet
总结这些viewset作用就是,将CRUD这些进行组合,并且重写了as_view以便于和路由对接。
Viewset实践
上一篇直接继承了ListCreateAPIView,现在使用封装后的Viewsets作为继承的视图类。
Views.py
新建一个class类
class GameModelViewSet(ModelViewSet):
serializer_class = GameSerializer
queryset = Game.objects.all()
urls.py
注册路由时,也可以使用as_view,但是比较麻烦,所以使用router来代替
router = DefaultRouter()
router.register(r'games', GameModelViewSet)
总URLS
from django.contrib import admin
from django.urls import path, include
from App.urls import router
urlpatterns = [
path('admin/', admin.site.urls),
# path('app/', include('App.urls')),
path('app/', include(router.urls)),
]
postman测试
get访问所有数据
post新建
get访问单个数据
delete步骤自行测试
restframework分页器
开发文档:https://q1mi.github.io/Django-REST-framework-documentation/api-guide/pagination_zh/
当开发完接口之后,需要实现接口数据的分片,比如每次只返回5条数据给客户端,而不是每次都返回全部数量这样能有效减少服务器压力,减少客户端的加载时间,提高响应速度,客户端需要携带参数访问接口。
分页器类型介绍
分页器分为三种:
- 常规单页分页器
- 通过page参数访问某一个单个分片数据
- 偏移分页
- 这种分页样式反映了查找多个数据库记录时使用的语法。客户端包括“limit”和“offset”查询参数。limit指示要返回的项目的最大数目,这相当于其他样式中的
page_size
。offset指示查询相对于完整的未分页项的起始位置。
- 游标分页
- 基于cursor的分页提供了一个不透明的“游标”指示器,客户端可以使用它对结果集进行分页。这种分页样式只显示正向和反向控件,而不允许客户端导航到任意位置。
基于cursor的分页要求结果集中的项具有唯一的、不变的顺序。此顺序通常可能是记录上的创建时间戳,因为它提为分页供了一致的顺序。
基于cursor的分页比其他方案更复杂。它还要求结果集呈现固定的顺序,并且不允许客户端任意索引结果集。但是,它确实提供了以下好处:
- 提供一致的分页视图。当恰当地使用时,`CursorPagination` 可以确保客户端在翻阅记录时永远不会看到同一个项目两次,即使在分页过程中其他客户端正在插入新的项目时亦是如此。
- 支持使用非常大的数据集。对于极其庞大的数据集,使用基于offset的分页样式进行分页可能会变得效率低下或无法使用。基于cursor的分页方案具有固定时间的属性,并且不会随着数据集大小的增加而减慢。
实践
首先在views中注册分页器:
class LargeResultsSetPagination(PageNumberPagination):
page_size = 2
page_size_query_param = 'page_size'
max_page_size = 8
在Viewset类视图中使用分页器:
class GameModelViewSet(ModelViewSet):
serializer_class = GameSerializer
queryset = Game.objects.all()
pagination_class = LargeResultsSetPagination
接着进行携带page参数get请求接口:
可以看到只返回了两条数据,并且客户端通过循环page参数,可继续读取下面的数据。
总结
router
使用了ViewSet,封装了路由的设置,可以直接使用router来自动设置路由路径
功能
想要实现对应的功能,只需要继承对应minxins中的类即可:
- mixins.CreateModelMixin
- mixins.RetrieveModelMixin
- mixins.UpdateModelMixin
- mixins.DestroyModelMixin
- mixins.ListModelMixin
APIView
子类
- generics包中
GenericAPIView
- 增加的模型的获取操作
- get_queryset
get_object
- lookup_field 默认pk
- get_serializer
- get_serializer_class
- get_serializer_context
- filter_queryset
- paginator
- paginate_queryset
- get_paginated_response
CreateAPIView
- 创建的类视图
- 继承自GenericAPIView
- 继承自CreateModelMixin
- 实现了post进行创建
ListAPIView
- 列表的类视图
- 继承自GenericAPIView
- 继承自ListModelMixin
- 实现了get
RetrieveAPIView
- 查询单个数据的类视图
- 继承自GenericAPIView
- 继承自RetrieveModelMixin
- 实现了get
DestroyAPIView
- 销毁数据的类视图,删除数据的类视图
- 继承自GenericAPIView
- 继承自DestroyModelMixin
- 实现了delete
UpdateAPIView
- 更新数据的类视图
- 继承自GenericAPIView
- 继承自UpdateModelMixin
- 实现了 put,patch
ListCreateAPIView
- 获取列表数据,创建数据的类视图
- 继承自GenericAPIView
- 继承自ListModelMixin
- 继承自CreateModelMixin
- 实现了 get,post
RetrieveUpdateAPIView
- 获取单个数据,更新单个数据的类视图
- 继承自GenericAPIView
- 继承自RetrieveModelMixin
- 继承自UpdateModelMixin
- 实现了 get, put, patch
RetrieveDestroyAPIView
- 获取单个数据,删除单个数据
- 继承自GenericAPIView
- 继承自RetrieveModelMixin
- 继承自DestroyModelMixin
- 实现了 get, delete
RetrieveUpdateDestroyAPIView
- 获取单个数据,更新单个数据,删除单个数据的类视图
- 继承自GenericAPIView
- 继承自RetrieveModelMixin
- 继承自UpdateModelMixin
- 继承自DestroyModelMixin
- 实现了 get, put, patch, delete
mixins
CreateModelMixin
- create
- perform_create
- get_success_headers
ListModelMixin
list
- 查询结果集,添加分页,帮你序列化
RetrieveModelMixin
retrieve
- 获取单个对象并进行序列化
DestroyModelMixin
destroy
- 获取单个对象
- 调用执行删除
- 返回Respon 状态码204
perform_destroy
- 默认是模型的delete
如果说数据的逻辑删除
- 重写进行保存
UpdateModelMixin
update
- 获取对象,合法验证
- 执行更新
- perform_update
partial_update
- 差量更新,对应的就是patch
viewsets
ViewSetMixin
- 重写as_view
GenericViewSet
- 继承自GenericAPIView
- 继承自ViewSetMixin
ViewSet
- 继承自APIView
- 继承自ViewSetMixin
- 默认啥都不支持,需要自己手动实现
ReadOnlyModelViewSet
- 只读的模型的视图集合
- 继承自RetrieveModelMixin
- 继承自ListModelMixin
- 继承自GenericViewSet
ModelViewSet
- 直接封装对象的所有操作
- 继承自GenericViewSet
- 继承自CreateModelMixin
- 继承自RetrieveModelMixin
- 继承自UpdateModelMixin
- 继承自DestroyModelMixin
- 继承自ListModelMixin
此处评论已关闭