何时将http方法映射到视图方法Django rest fram

2024-04-23 08:31:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我见过这样实现的视图集:

我们能否在django rest frameworks文档中展开这一行代码:

如果需要,可以将此视图集绑定到两个单独的视图中,如下所示:

user_list = UserViewSet.as_view({'get': 'list'})
user_detail = UserViewSet.as_view({'get': 'retrieve'})

user_list和{}将连接/使用在哪里?在

在使用视图集或通用视图时,何时映射http方法?在

因为我看到过这样的例子:视图集不使用映射而使用它们。我们能谈谈这是怎么工作的吗?它是如何连接的吗?在

^{pr2}$

还有这是怎么回事:

@detail_route(methods=['post'])
    def set_password(self, request, pk=None):

如果我们有路由修饰符,为什么还要在url映射中使用呢?它们之间有什么区别?在


Tags: django代码文档view视图restgetas
1条回答
网友
1楼 · 发布于 2024-04-23 08:31:40

对于第一个关于连接UserViewSet的问题,您可以在url文件中使用如下内容:

urlpatterns = [
    url(
        r'^users/$',
        UserViewSet.as_view({'get': 'list'}),
        name='user-list',
    ),
    url(
        r'^users/(?P<pk>\d+)/$',
        UserViewSet.as_view({'get': 'retrieve'}),
        name='user-detail',
    ),
]

这是使用视图集的用户模型的只读实现。如果要列出可以请求/users/的所有用户,并且要获得id为1的用户,则需要请求/users/1/。在

这里您应该理解的是,有一些操作作用于您的模型,例如列出用户或创建新用户,以及作用于模型的实例的操作。例如,如果要检索、更新或删除用户实例,则需要在URL中包含users主键,以便获取该用户。在

您的TaskViewSet不是只读的,所以让我们看看该类应该是什么样子。在

^{pr2}$

这是一个简单、通用的ModelViewSet,可以在URL文件中实现,如下所示:

urlpatterns = [
    url(
        r'^tasks/$',
        TaskViewSet.as_view({'get': 'list', 'post': 'create'}),
        name='task-list',
    ),
    url(
        r'^tasks/(?P<pk>\d+)/$',
        TaskViewSet.as_view({'get': 'retrieve', 'put': 'update', 'patch': 'partial_update', 'delete': 'destroy'}),
        name='task-detail',
    ),
]

现在,您可以对模型执行任何操作,可以列出、创建、检索、更新和删除对象。您将看到这里使用ModelViewSet形成了一个模式,这就是路由器的便利性突出的地方。Django-Rest框架路由器实现基本上是通过获取一个路径和一个视图集,然后构造url来实现的。在

在本例中,我们使用SimpleRouter生成url模式。在

router = SimpleRouter()
router.register('users', UserViewSet)  # UserViewSet is ReadOnlyModelViewSet
router.register('tasks', TaskViewSet)  # TaskViewSet is ModelViewSet
urlpatterns = [] + router.urls

这将产生:

urlpatterns = [
    url(
        r'^users/$',
        UserViewSet.as_view({'get': 'list'}),
        name='user-list',
    ),
    url(
        r'^users/(?P<pk>\d+)/$',
        UserViewSet.as_view({'get': 'retrieve'}),
        name='user-detail',
    ),
    url(
        r'^tasks/$',
        TaskViewSet.as_view({'get': 'list', 'post': 'create'}),
        name='task-list',
    ),
    url(
        r'^tasks/(?P<pk>\d+)/$',
        TaskViewSet.as_view({'get': 'retrieve', 'put': 'update', 'patch': 'partial_update', 'delete': 'destroy'}),
        name='task-detail',
    ),
]

我希望到目前为止这是有意义的,并且您可以看到如何使用这些类来减少需要编写的代码量。在

现在我将解释@detail_route和{}装饰器在做什么。这些修饰符帮助路由器类在视图集中注册自定义方法。在

For rest framework 3.8 and above ^{} and ^{} have been deprecated in favour of the ^{} decorator@detail_route(...)替换为@action(detail=True, ...)。 将@list_route(...)的用法替换为@action(detail=False, ...)。在

您应该使用@list_route修饰符来执行对模型调用有意义的操作,而不是模型的一个实例,例如,如果您希望提供某个端点以将模型上的报告下载为csv。您应该使用@detail_route装饰器来执行模型实例的操作。我将扩展之前的TaskViewSet示例。在

class TaskViewSet(ModelViewSet):
    queryset = Task
    serializer_class = TaskSerializer
    lookup_field = 'pk'  # This is the default
    lookup_url_kwarg = 'pk'  # This is the default

    @list_route(methods=['get'])
    def download(self, request, *args, **kwargs):
        """Download queryset as xlsx"""
        qs = self.get_queryset()
        return queryset_to_excel(qs)  # simple example

    @detail_route(methods=['get'])
    def details(self, request, *args, **kwargs):
        """Return intricate details of Task"""
        object = self.get_object()
        return object.get_intricate_task_details()

如果我们将此TaskViewSet与路由器一起使用:

router = SimpleRouter()
router.register('tasks', TaskViewSet)
urlpatterns = [] + router.urls

我在列表中添加了一个download方法,将queryset作为Excel文件下载,并向detail添加了一个details方法,它将返回一些额外的信息,这些信息可能很难检索,因此我们不希望它出现在普通的detail响应中。然后我们将得到一个url配置,如:

urlpatterns = [
    url(
        r'^tasks/$',
        TaskViewSet.as_view({'get': 'list', 'post': 'create'}),
        name='task-list',
    ),
    url(
        r'^tasks/download/$',
        TaskViewSet.as_view({'get': 'download'}),
        name='task-download',
    ),
    url(
        r'^tasks/(?P<pk>\d+)/$',
        TaskViewSet.as_view({'get': 'retrieve', 'put': 'update', 'patch': 'partial_update', 'delete': 'destroy'}),
        name='task-detail',
    ),
    url(
        r'^tasks/(?P<pk>\d+)/details/$',
        TaskViewSet.as_view({'get': 'detail'}),
        name='task-details',
    ),
]

路由器现在已经为TaskViewSet上定义的自定义方法生成了其他路由。在

我建议您阅读一下关于ViewSet和SimpleRouter的rest框架文档。在

http://www.django-rest-framework.org/api-guide/viewsets/#modelviewset
http://www.django-rest-framework.org/api-guide/routers/#simplerouter

相关问题 更多 >