Django REST framework 第六章 ViewSets & Routers
REST framework包含了一个可以处理ViewSets的抽象, 它允许开发人员专注于API的状态跟交互进行建模,并使得URL构建结构基于通用的约定自动处理。
ViewSet类跟View类几乎相同,除此之外它提供了一些其他的操作,比如read或update,而不像view的get和put
一个ViewSet类最后只能绑定到一组方法处理程序,当它被实例化成一组视图时,经常使用一个Router类来处理定义的复杂的URL配置
Refactoring to use ViewSets
让我们用现在的views来重构成viewsets. 首先,将UserList和UserDetail视图重构成一个单独的UserViewSet. 可以移除掉这两个视图,用下面的代替它们
from rest_framework import viewsets class UserViewSet(viewsets.ReadOnlyModelViewSet):
"""
This viewset automatically provides `list` and `detail` actions.
"""
queryset = User.objects.all()
serializer_class = UserSerializer
这里我们已经使用了ReadOnlyModelViewSet类自动提供默认的只读操作。当我们使用正常视图,仍然要明确设置queryset和serializer_class属性,但我们再也不用向2个不同的类提供相同的信息。
然后我们将要替换SnippetList, SnippetDetail和SnippetHighlight视图类. 同样的可以移除这三个类,使用一个单独的类:
from rest_framework.decorators import action
from rest_framework.response import Response class SnippetViewSet(viewsets.ModelViewSet):
"""
This viewset automatically provides `list`, `create`, `retrieve`,
`update` and `destroy` actions. Additionally we also provide an extra `highlight` action.
"""
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,
IsOwnerOrReadOnly,) @action(detail=True, renderer_classes=[renderers.StaticHTMLRenderer])
def highlight(self, request, *args, **kwargs):
snippet = self.get_object()
return Response(snippet.highlighted) def perform_create(self, serializer):
serializer.save(owner=self.request.user)
此时为了获取完整的读写操作集,我们使用了ModelViewSet. 注意我们已经使用了@action装饰器来创建一个定制化的操作,叫做highlight. 这个装饰器能够被使用来添加任何的定制化终端,不在需要匹配标准的create/update/delete风格.
使用@action装饰器的自定义操作默认响应GET请求. 我们可以使用methods参数,如果我们向一个操作响应POST请求
默认情况下自定义操作的url依赖于方法名称本身. 如果你想改变URL的构成,你可以引入url_path作为一个装饰器关键字参数
Binding ViewSets to URLs explictily
当我们定义URL设置,处理方法只能得到给定的操作。想知道内部具体做了写什么,让我们首先明确地用ViewSets创建一个视图
在app内的urls文件中绑定ViewSets:
from app01.views import SnippetViewSet, UserViewSet, api_root
from rest_framework import renderers snippet_list = SnippetViewSet.as_view({
'get': 'list',
'post': 'create'
})
snippet_detail = SnippetViewSet.as_view({
'get': 'retrieve',
'put': 'update',
'patch': 'partial_update',
'delete': 'destroy'
})
snippet_highlight = SnippetViewSet.as_view({
'get': 'highlight'
}, renderer_classes=[renderers.StaticHTMLRenderer])
user_list = UserViewSet.as_view({
'get': 'list'
})
user_detail = UserViewSet.as_view({
'get': 'retrieve'
})
注意一下,我们是如何创建每一个ViewSets类的多个视图,为每一个视图绑定http方法跟需要的操作
urlpatterns = [
path('snippets/', snippet_list, name='snippet-list'),
path('snippets/<int:pk>/', snippet_detail, name='snippet-detail'),
path('users/', user_list, name='user-list'),
path('users/<int:pk>/', user_detail, name='user-detail'),
path('snippets/<int:pk>/highlight/', snippet_highlight, name='snippet-highlight'),
path('', views.api_root),
]
urlpatterns = format_suffix_patterns(urlpatterns)
Using Router
因为想比于View类我们使用了ViewSet类,事实上就没必要再自己设计URL设定了。将资源连接到views和urls的约定可以使用Router类. 所有我们要做的只是注册用路由注册一个合适的视图集,让我们做完剩下的。
修改app内的urls文件
from django.conf.urls import url, include
from rest_framework.routers import DefaultRouter
from app01 import views # Create a router and register our viewsets with it.
router = DefaultRouter()
router.register(r'snippets', views.SnippetViewSet)
router.register(r'users', views.UserViewSet) # The API URLs are now determined automatically by the router.
urlpatterns = [
url(r'^', include(router.urls))
]
用路由器注册视图集类似于提供URL模式。我们包括两个参数——视图的URL前缀和视图集本身。
使用的DefaultRouter类也自动为我们创建API根视图,所以我们现在可以从views中删除api_root方法。
Django REST framework 第六章 ViewSets & Routers的更多相关文章
- Django Rest Framework(3)-----APIView与Viewsets
REST framework提供了一个APIView类,它是Django的View类的子类. REST framework主要的几种view以及他们之间的关系: mixins 到目前为止,我们使用的创 ...
- Django REST framework 第五章 Relationships & Hyperlinked APIs
到目前为止,API内部的关系是使用主键来代表的.在这篇教程中,我们将提高API的凝聚力和可发现性,通过在相互关系上使用超链接. Creating an endpoint for the root of ...
- Django REST framework 第四章 Authentication
到目前为止,撰写的API没有任何限制关于谁能更新.删除snippet. 我们更想要一些高级行为来确保: 1.代码段总是跟创建者有关联 2.只要认证通过的用户才能创建 3.只有创建者有权限更新或者删除 ...
- Django REST framework 第三章 CBV
从介绍Django快开始,我们就一直在使用FBV的方式来撰写代码,二者本质上并没有太大的区别,然而到了REST framework,更会倾向于用CBV来写API的视图,后面会看到这个方式的强大,它允许 ...
- Django REST framework 第七章 Schemas & client libraries
模式是一个机器可读文档,描述可用的API端点,URL以及它们支持的操作. 模式对于自动生成文档是一个很有用的工具,也可以用来动态调用可以于API交互的客户端库. Core API 为了提供模式支持,R ...
- Django REST FrameWork中文教程2:请求和响应
从这一点开始,我们将真正开始覆盖REST框架的核心.我们来介绍几个基本的构建块. 请求对象REST框架引入了Request扩展常规的对象HttpRequest,并提供更灵活的请求解析.Request对 ...
- Django REST framework 中文教程1:序列化
建立环境 在我们做任何事情之前,我们将使用virtualenv创建一个新的虚拟环境.这将确保我们的包配置与我们正在开展的任何其他项目保持良好的隔离. virtualenv envsource env/ ...
- 《Entity Framework 6 Recipes》中文翻译系列 (30) ------ 第六章 继承与建模高级应用之多对多关联
翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 第六章 继承与建模高级应用 现在,你应该对实体框架中基本的建模有了一定的了解,本章 ...
- 《Entity Framework 6 Recipes》中文翻译系列 (37) ------ 第六章 继承与建模高级应用之独立关联与外键关联
翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 6-13 在基类中应用条件 问题 你想从一个已存在的模型中的实体派生一个新的实体, ...
随机推荐
- MFC读写配置ini文件
https://blog.csdn.net/naibozhuan3744/article/details/78783446 https://blog.csdn.net/rayborn1105/arti ...
- 第二十九篇-Fragment动态用法
效果图: 上节学习了静态添加Fragment的方法,这节学习动态添加方法. 主页面 layout.xml Fragment页面 layout2.xml 实现功能,当点击主页面的button时,将Fra ...
- Ubuntu下安装Goldendict(翻译软件)
Ubuntu直接安装 sudo apt-get install goldendict 通过源码安装 失败 下载词典 http://blog.sina.com.cn/s/blog_c58823b3010 ...
- 114. Flatten Binary Tree to Linked List(M)
. Flatten Binary Tree to Linked List Given a binary tree, flatten it to a linked list in-place. For ...
- centos7.2安装完成的基本操作
系统是centos7.2,安装完成的基本操作 1 修改网卡为eth02 更新系统3 给/etc/rc.local添加执行权限4 添加用户hequan5 禁用selinux6 关闭防火墙安装iptabl ...
- NGUI使用图集的精灵换图片
创建了一个sprite,选择的是某一个图集下的sprite,现在我想点击它来换图片.前提是你的sprite已经加了UIButton 代码如下: public void OnClick() { if ( ...
- 01--STL泛型编程了解
开始学习侯捷老师的课程了~~ 一:六大组件关系 容器(Container) 算法(Algorithm) 迭代器(Iterator) 仿函数(Function object) 适配器(Adaptor) ...
- springboot下整合redis使用redisTemplate模板
pom <!-- 引入 redis 依赖 --> <dependency> <groupId>org.springframework.boot</groupI ...
- vue报错:/node_modules/babel-loader/lib!./node_modules/vue-loader/lib/selector.js?
vue项目中报这样的错误:./node_modules/babel-loader/lib!./node_modules/vue-loader/lib/selector.js? 大部分是因为文件的路径有 ...
- 解决mysql:Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (111)
(一)出现问题的的报错信息 Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (111) ( ...