欢迎来访我的博客。

Django Rest Framework学习总结-6:ViewSets和Routers

Django 小张哥哥 515浏览 1评论

REST framework里面有一写抽提出来的类用于处理ViewSets。这可以让我们在开发的时候专注于模型和API之间的交互,而URL链接的构建则能自动进行处理。

ViewSet类和View类基本是相同的,除了ViewSet提供read或者update的操作,而不是get或者put这些操作方法。
一个ViewSet只是在实例化成为一组视图实例的最后才会和一组操作方法绑定。绑定时候可以通过Router类来帮我们处理这些繁复的URL配置。


使用ViewSet重构代码

将我们当前的view视图使用ViewSet进行重构。
首先,我们先重构一下我们的UserListUserDetail视图。我们可以直接删除这两个视图,用下面这个类替代它们。

from rest_framework import viewsets
class UserViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer

在这里,我们使用了ReadOnlyModelViewSet类,自动提供了默认的只读权限。和之前视图一样,我们设置一下querysetserializer_class属性就行了。不需要再分别写两个类。

下面,我们来替换一下SnippetListSnippetDetailSnippetHighlight视图类。我们同样删除这三个视图,直接使用下面一个代替:

from rest_framework.decorators import action
from rest_framework.response import Response


class SnippetViewSet(viewsets.ModelViewSet):
    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/udpate/delete操作之外的,用户自定义操作。如果我们希望操作用在POST方法的request请求时,我们可以使用methods参数。
自定义的这些actions在默认情况下的url是由方法的名称确定的,如果想要改变url的名成,可以在装饰器的参数中输入url_path作为参数。


绑定ViewSets到URL

snippets/urls.py文件中,我们将ViewSet类绑定到不同的视图中。

from snippets.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': 'udpate',
    'patch': 'partial_updata',
    'delete': 'destory',})snippet_highlight = SnippetView.as_view({
    'get': 'highlight',})user_list = UserViewSet.as_view({
    'get':'list',})user_detail = UserViewSet.as_view({
    'get': 'retrieve',})

可以看到,我们通过绑定http方法到每个视图对应的所用的方法上,从ViewSet中创建出了多个视图。
现在,我们已经将我们的资源绑定到了单独的视图上,然后就可以继续照常将这些视图注册到URL上。

urlpatterns = format_suffix_patterns([
    path('', api_root),
    path('snippets/', snippet_list, name='snippet-list'),
    path('snippets/<int:pk>/', snippet_detail, name='snippet-detail'),
    path('snippets/<int:pk>/highlight/', snippet_highlight, name='snippet-highlight'),
    path('users/', user_list, name='user-list'),
    path('users/<int:pk>/', user_detail, name='user-detail')])

使用Routers

由于使用的是ViewSet类而不是View类,我们并不需要自己去设置URL。使用Router类可以自动将这些视图和urls自动处理好。我们需要做的就是将这些视图注册到一个router上,剩下的就交给它去处理。

重新改写我们的snippets/urls.py文件:

from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import UserViewSet, SnippetViewSet


router = DefaultRouter()
router.register('snippets', SnippetViewSet)
router.register('users', UserViewSet)

urlpatterns = [
    path('', include(router.urls)),
]


将这些viewset注册到router上和我们自己写一个urlpattern是相同的。注册时,我们提供了两个参数,一个是URL前缀,一个是viewset它自己。
我们所使用的DefauRouter类自动帮我们创建API视图,我们现在可以从views模块中删除掉api_root方法了。


views和viewsets比较

viewsets很有用,可以保证我们整个API的URL的设置保存一致,并且可以最大幅度上减少代码的书写,让我们把开发的精力使用到你的API其它开发部分。

但是,viewset也并不是一直都是最合适的。就跟使用基于类的视图和基于函数的视图两者比较一样, 在使用viewsetsviews之间,我们也需要有一个权衡。虽然viewset能够帮我们处理很多繁复的东西,但是使用viewsets写出来的代码则明显没有使用views写出来的代码清楚明了,而清晰明了,功能划分有序的代码在实际的开发过程中也是很重要的。



本文中的源码可以在Github上查看。点我查看本文源码



转载请注明:禅思 » Django Rest Framework学习总结-6:ViewSets和Routers?

喜欢 (3) or 分享 (0)

我的个人微信公众号,欢迎关注

扫码或搜索:Python后端开发Django

Python后端开发Django

微信公众号 扫一扫关注

结交朋友、一起学习,一起进步。

科波之主

QQ号 386046154 立即加入

添加微信,进行技术交流

专注技术交流, 一同成长进步

我的微信号

如果您喜欢我的文章,感觉我的文章对您有帮助,请狠狠点击下面

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
(1)个小伙伴在吐槽
    1. cheap viagra indian pharmacy viagra viagra sales austra http://genqpviag.com/ - cheap viagra with other than visa card ’
      Lbgamomi 2021-01-25 23:50:32 回复