Rest framework 学习(6) ViewSets和路由器

ViewSets: 提供一组操作行为action,例如:list(),retrieve(),create(),update(),destory()等,不再提供get,post方法了。其下多种ModelViewSet能提供更简便的开发方式。

注册路由:自动处理将资源连接到视图和URL的约定。将不同http请求与ViewSets不同方法,一一映射起来。

重构以使用ViewSet

重构我们UserList和UserDetail意见纳入一个单一的UserViewSet。我们可以删除这两个视图,并用一个类替换它们:

# class UserList(generics.ListAPIView):
#     queryset = User.objects.all()
#     serializer_class = UserSerializer
# class UserDetail(generics.RetrieveAPIView):
#     queryset = User.objects.all()
#     serializer_class = UserSerializer

# ViewSets

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

#  This viewset automatically provides `list` and `detail` actions.

重构SnippetList,SnippetDetail和SnippetHighlight视图类,用一个类替换它们。

# class SnippetList(generics.ListCreateAPIView):
#     queryset = Snippet.objects.all()
#     serializer_class = SnippetSerializer
#     permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
#
#     def perform_create(self, serializer):
#         # 保存之前按,加入owner信息
#         # 通过覆盖我们的代码段视图上的方法,允许我们修改实例保存的管理方式,并处理传入请求或请求的URL中隐含的任何信息。
#         serializer.save(owner=self.request.user)
#
#
# class SnippetDetail(generics.RetrieveUpdateDestroyAPIView):
#     queryset = Snippet.objects.all()
#     serializer_class = SnippetSerializer
#     permission_classes = (permissions.IsAuthenticatedOrReadOnly,IsOwnerOrReadOnly)
#
#
# class SnippetHighlight(generics.GenericAPIView):
#     queryset = Snippet.objects.all()
#     renderer_classes = (renderers.StaticHTMLRenderer,)
#
#     def get(self, request, *args, **kwargs):
#         snippet = self.get_object()
#         return Response(snippet.highlighted)

# 修改SnippetList, SnippetDetail and SnippetHighlight,成为一个类
from rest_framework.decorators import action
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请求,我们可以通过@action(method='POST',...) 进行实现构造post请求
  • 默认情况下,自定义操作的URL取决于方法名称本身。如果要更改url的构造方式,可以包含url_pathdecorator关键字参数

将ViewSets明确绑定到URL

这里,我们主要探求ViewSet如何通过将http方法绑定到每个视图所需的操作的。

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': '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'
})

将资源绑定到具体视图中,我们可以像往常一样使用URL conf注册视图。

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')
])


# 这里注意,path(route, view, kwargs=None, name=None)参数,view填写上面我们生成的视图

使用路由器

因为我们使用的是ViewSet类而不是View类,所以我们实际上不需要自己设计URL。可以使用Router类自动处理将资源连接到视图和URL的约定。

这是我们的重写snippets/urls.py文件。

from django.urls import path, include
from rest_framework.routers import DefaultRouter
from snippets 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 = [
    path('', include(router.urls)),
]

向路由器注册视图集与提供urlpattern类似。我们包括两个参数 - 视图的URL前缀和视图集本身。

我们正在使用的DefaultRouter类也会自动为我们创建api_root根视图,因此我们可以删除掉# snippets/views
模块中的api_root方法而不会有任何影响。

# snippets/views.py
# # 給API_ROOT 添加API 端点
# @api_view(['GET'])
# def api_root(request, format=None):
#     return Response({
#         'users': reverse('user-list', request=request, format=format),
#         'snippets': reverse('snippet-list', request=request, format=format)
#     })

视图与视图集之间的权衡

使用视图集可能是一个非常有用的抽象。它有助于确保URL约定在您的API中保持一致,最大限度地减少您需要编写的代码量,并使您可以专注于API提供的交互和表示,而不是URL conf的细节

但是,使用视图集不如单独构建视图那么明确。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
学习 Django Rest Framework(DRF)需要掌握以下几个步骤: 1. Django 基础:首先需要了解 Django 框架的基础知识,包括 Django 的设置、路由、视图、模板等概念。 2. REST 架构:了解 REST(Representational State Transfer)架构的概念和基本原则,包括资源、路由、状态码、请求方法等。 3. DRF 安装和配置:在 Django 项目中安装 DRF,并熟悉其基本配置,包括设置路由、生成 API 文档等。 4. 创建 API 接口:使用 DRF 创建各种 API 接口,包括用户管理、博客文章管理、评论管理等。 5. 数据库操作:熟悉 Django ORM(对象关系映射)的使用,通过 ORM 进行数据库操作。 6. 过滤器和分页器:了解 DRF 的过滤器和分页器,以及如何在 API 接口中使用这些功能。 7. 安全性和认证:熟悉 DRF 的认证和安全机制,包括 Token、JWT 等认证方式,以及 CSRF 保护等安全措施。 8. 测试和调试:熟悉 DRF 的测试框架,编写测试用例并进行调试。 9. 进阶功能:了解 DRF 的进阶功能,如自定义渲染器、过滤器、视图等,以及如何使用 DRF 与其他框架集成。 学习路线可以按照以上步骤进行,具体可以参考以下建议: * 阅读 Django 和 DRF 的官方文档,了解其基本概念和用法。 * 学习 Django 中相关的第三方库,如 Django REST Auth(Django REST 的认证库)和 Django Rest Clients(用于与 API 进行交互的客户端库)。 * 通过实践案例来掌握 DRF 的使用,可以参考一些开源项目中的 API 接口,并尝试自己创建类似的接口。 * 参与社区讨论和问答平台,与其他开发者交流学习心得和解决问题。 * 参加线上或线下培训课程,获取更系统化的学习体验。 总之,学习 DRF 需要不断实践和积累经验,建议按照以上步骤逐步深入学习,并结合实际案例来加深理解。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值