别院牧志知识库 别院牧志知识库
首页
  • 基础

    • 全栈之路
    • 😎Awesome资源
  • 进阶

    • Python 工匠系列
    • 高阶知识点
  • 指南教程

    • Socket 编程
    • 异步编程
    • PEP 系列
  • 面试

    • Python 面试题
    • 2025 面试记录
    • 2022 面试记录
    • 2021 面试记录
    • 2020 面试记录
    • 2019 面试记录
    • 数据库索引原理
  • 基金

    • 基金知识
    • 基金经理
  • 细读经典

    • 德隆-三个知道
    • 孔曼子-摊大饼理论
    • 配置者说-躺赢之路
    • 资水-建立自己的投资体系
    • 反脆弱
  • Git 参考手册
  • 提问的智慧
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
首页
  • 基础

    • 全栈之路
    • 😎Awesome资源
  • 进阶

    • Python 工匠系列
    • 高阶知识点
  • 指南教程

    • Socket 编程
    • 异步编程
    • PEP 系列
  • 面试

    • Python 面试题
    • 2025 面试记录
    • 2022 面试记录
    • 2021 面试记录
    • 2020 面试记录
    • 2019 面试记录
    • 数据库索引原理
  • 基金

    • 基金知识
    • 基金经理
  • 细读经典

    • 德隆-三个知道
    • 孔曼子-摊大饼理论
    • 配置者说-躺赢之路
    • 资水-建立自己的投资体系
    • 反脆弱
  • Git 参考手册
  • 提问的智慧
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 辨析

  • Sockets编程

  • Django

    • Django 学习资料收集
    • Django-REST-framework教程中文版

      • Django-REST-framework 教程中文版
      • 快速入门
      • 教程 1:序列化
      • 教程 2:Requests 和 Responses
      • 教程 3:类视图
      • 教程 4:认证和权限
      • 教程 5:Relationships 和 Hyperlinked
      • 教程 6:ViewSets 和 Routers
        • 使用 ViewSet 重构代码
        • 显式绑定 URL 和 ViewSets
        • 使用 Routers
        • 权衡 Views 和 Viewsets
        • 总结
        • 展望
  • stackoverflow

  • Flask

  • 全栈之路

  • 面试

  • 代码片段

  • 异步编程

  • 😎Awesome资源

  • PEP

  • Python工匠系列

  • 高阶知识点

  • Python 学习资源待整理
  • 设计模式

  • 好“艹蛋”的 Python 呀!
  • FIFO | 待学清单📝
  • pip 安装及使用
  • 数据分析

  • 源码阅读计划

  • OOP

  • 关于 python 中的 setup.py
  • 并行分布式框架 Celery
  • 七种武器,让你的代码提高可维护性
  • 使用 pdb 调试 Python 代码
  • 每周一个 Python 标准库
  • 🐍Python
  • Django
  • Django-REST-framework教程中文版
佚名
2021-04-13
目录

教程 6:ViewSets 和 Routers

REST framework 提供了一种叫做ViewSets的抽象行为,它可以使开发人员聚焦于 API 的状态和实现,基于常见的约定而自动进行 URL 配置。

ViewSet和View很像,除了它提供的是read以及update操作而不是 HTTP 的get或者post。

ViewSet仅在被调用的时候才会和对应的方法进行绑定,当它被实例化时——通常是在使用Route类管理 URL 配置的时候。

# 使用 ViewSet 重构代码

首先我们使用但一个UserViewSet来取代UserList和UserDetail,我们先移除那两个类,并添加:

from rest_framework import viewsets

class UserViewSet(viewsets.ReadOnlyModelViewSet):
    """
    This viewset automatically provides `list` and `detail` actions.
    """
    queryset = User.objects.all()
    serializer_class = UserSerializer
1
2
3
4
5
6
7
8

现在我们使用ReadOnlyModelViewSet自动提供了“只读”方法,并且依然想使用常规视图是那样设置了queryset和seriallizer_class属性,但我们不需要写 2 个类了。

下面我们修改SnippetList、SnippetDetail和SnippetHighlight类,同样删除它们并修改成一个类:

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

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)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

这次我们使用ModelViewSet来获取完整的读和写操作。

注意,我们还使用了@action装饰器来创建一个名为highlight的自定义操作。这个装饰器可以用来添加任何不符合标准create/update/delete类型的自定义端点。

默认情况下,使用@action装饰器的自定义操作将响应GET请求。如果我们想要一个响应POST请求的操作,我们可以使用methods参数指定。

默认情况下,自定义操作的 url 取决于方法名称本身。如果你想改变 url 的构造方式,你可以把url_path作为装饰器关键字参数。

# 显式绑定 URL 和 ViewSets

仅仅在我们定义 URL 配置时 HTTP 方法才会和我们定义的行为进行绑定。为了理解细节,我们先显式的在urls.py中进行操作:

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'
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

注意我们为每个ViewSet都创建了多个 View,并且为每个 View 的行为和 HTTP 方法进行了绑定。

绑定后,我们可以像平常那样定义 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')
])
1
2
3
4
5
6
7
8

# 使用 Routers

因为我们使用了ViewSet而不是View,实际上我们不需要自己定义 URL。使用Router类可以自动的进行上述操作,我们需要做的仅仅是正确的注册 View 到 Router 中: 我们重写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)),
]
1
2
3
4
5
6
7
8
9
10
11
12
13

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

我们正在使用的DefaultRouter类也会自动为我们创建 API 根视图,所以我们现在可以从views模块中移除api_root方法。

# 权衡 Views 和 Viewsets

viewsets 是一种很用的抽象,它帮助我们确保 URL 符合惯例,减少代码编写量,使你专注于 API 交互和设计而不是 URL 配置上。

但这并不意味这总是一种好的选择,就好象函数视图和类视图之间的权衡一样,使用 viewsets 相比于显式构建 vews,有些隐晦。

# 总结

通过少量的代码,我们构建出一个完备的 Web API,完美支持浏览器访问、用户认证、权限管理,并且支持多种返回格式。

我们经历了每步设计的过程,并且知道了如果我们需要自定义功能,可以方便的使用 Django 原生的 views.

你可以在github (opens new window)上找到最终的代码,以及模拟程序 (opens new window)。

# 展望

整个教程到这就结束了,如果你想得到更多信息,这里有几点建议:

  • 在Github (opens new window)提问并且提交 pull requests。
  • 加入[REST framework discussion 组](https://groups.google.com/forum/?fromgroups target=)并为社区做贡献。
  • 在 Twitter 上跟随作者 (opens new window)并 say hi。
编辑 (opens new window)
#DRF
上次更新: 2024-07-23, 01:00:43
教程 5:Relationships 和 Hyperlinked
StackOverflow Python 相关问题精选

← 教程 5:Relationships 和 Hyperlinked StackOverflow Python 相关问题精选→

最近更新
01
2025 面试记录
05-28
02
提升沟通亲和力的实用策略
03-26
03
工作
07-15
更多文章>
Theme by Vdoing | Copyright © 2019-2025 IMOYAO | 别院牧志
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式