DynamicListRoute与自定义路由器 - Django Rest Framework

时间:2017-01-31 18:46:35

标签: django-rest-framework

我做了什么(工作)

ModelViewSet

class UserViewSet(viewsets.ModelViewSet):
    """
    A viewset for viewing and editing user instances.
    """
    permission_classes = [IsAuthenticated, IsUser]
    serializer_class = UserSerializer
    queryset = User.objects.all()

    @list_route(methods=['GET','PUT'])
    def me(self, request, *args, **kwargs):
        self.kwargs.update(pk=request.user.id)
        if request.method == 'GET':
            return self.retrieve(request,*args, **kwargs)
        else:
            return self.update(request,*args, **kwargs)

注意:

  • UserSerializer是用户对象的简单ModelSerializer。
  • IsUser是一个权限类,用于验证obj.id == request.user.id

SimpleRouter

router = SimpleRouter(trailing_slash=False)
router.register(r'users', UserViewSet)

urlpatterns += router.urls

注意:

  • 路径不会从这里开始,但我会假设它确定了端点的名称。

所以现在我已经获得了SimpleRouter Documentation中描述的路线,基本上是每个传统的端点,加上:

  • 网址格式:users/me
  • HTTP方法:GET和PUT(由methods参数指定)
  • 行动:me@list_route装饰方法)
  • 网址名称:user-me

我的要求

  • GET /users/me返回JSON编码的User对象。
  • PUT /users/me更新User对象并返回更新的JSON编码User对象。

我想要的(不工作)

我不需要,也不想要SimpleRouter创建的所有路线。

自定义路由器

class CustomRetrieveUpdateRouter(SimpleRouter):
    routes = [
        Route(
            url=r'^{prefix}/{lookup}{trailing_slash}$',
            mapping={'get': 'retrieve'},
            name='{basename}-detail',
            initkwargs={'suffix': 'Detail'}
        ),
        Route(
            url=r'^{prefix}/{lookup}{trailing_slash}$',
            mapping={'put': 'update'},
            name='{basename}-detail',
            initkwargs={'suffix': 'Detail'}
        ),
        DynamicListRoute(
            url=r'^{prefix}/{methodname}{trailing_slash}$',
            name='{basename}-{methodnamehyphen}',
            initkwargs={}
        )
    ]

我的要求

  • GET /users/me返回以下JSON正文:{"detail":"Not found."}404错误代码。
  • PUT /users/me返回以下JSON正文:{"detail":"Method \"PUT\" not allowed."}405错误代码。

注意:

在Debug中如果我执行返回404的请求,HTML页面将显示以下可用端点:

  • ^users/(?P<pk>[^/.]+)$ [name='user-detail']
  • ^users/(?P<pk>[^/.]+)$ [name='user-detail']
  • ^users/me$ [name='user-me']

我忘了什么?

1 个答案:

答案 0 :(得分:1)

您的路线似乎存在冲突。

^users/(?P<pk>[^/.]+)$应该抓住&#34; / users / me&#34;因此它没有机会达到你的特定观点。

将pk url kwargs regexp设置为更具体的内容(如id的整数)或在另外两个Route之前设置DynamicListRoute。