如何强制对UpdateModelMixin的覆盖发布方法进行权限检查?

时间:2019-03-26 10:36:33

标签: django django-rest-framework

我被迫写一些杂乱的工作,我需要创建partial_update视图,但是它必须使用POST方法,因为最后该软件不使用PUT / PATCH方法。

以下是一些假设:

  • 一切都需要通过DefaultRouter()中的urls.py进行路由-这就是 为什么我使用GenericViewSet

  • 必须使用POST方法来更新一个字段-这就是为什么我要覆盖post()的{​​{1}}方法的原因

  • UpdateModelMixin是一个布尔值,一旦instance.visible不为空,该状态就会设置为True

更新有效,但body除外。它完全不检查请求的有效凭据。我认为是因为我完全重写了permission_classess,对吗?如何在post方法中强制进行身份验证检查?

urls.py

post()

views.py

from django.urls import include, path
from rest_framework import routers
from browse.views import *

router = routers.DefaultRouter()
[...]
router.register(r'update-article', UpdateArticleBodyViewSet)

urlpatterns = [
    path('api/', include(router.urls)),
    path('api-auth/', include('rest_framework.urls', namespace='rest_framework'),)
]

更新

我在第一个问题之后更改了代码,现在看起来像这样:

views.py

class UpdateArticleBodyViewSet(mixins.UpdateModelMixin, viewsets.GenericViewSet):
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer
    permission_classes = (permissions.IsAuthenticated, )

    def post(self, request, pk):
        instance = get_object_or_404(Article, pk=pk)
        instance.body = request.data.get("body")
        if instance.body:
            instance.visible = True
        instance.save()
        serializer = self.get_serializer(instance=instance, data=request.data, partial=True)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

urls.py

class UpdateArticleBodyViewSet(mixins.UpdateModelMixin, viewsets.GenericViewSet):
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer
    permission_classes = (permissions.IsAuthenticated, )

    def partial_update(self, request, *args, **kwargs):
        instance = self.queryset.get(pk=kwargs.get('pk'))
        instance.body = request.data.get("body")
        if instance.body:
            instance.visible = True
        instance.save()
        serializer = self.get_serializer(instance=instance, data=request.data, partial=True)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

这将导致以下错误: articles_viewset = UpdateArticleBodyViewSet.as_view({ 'post': 'update' }) router = routers.DefaultRouter() router.register(r'update-article', articles_viewset, basename="article")

在StackOverflow上已经有几个问题,但是没有一个提供答案。在这种情况下,有什么方法可以使用路由器吗?还是我被迫明确地编写网址?

1 个答案:

答案 0 :(得分:0)

这里的问题是,您要从其继承的两个类都没有一个post方法,因此您实际上并没有覆盖它。因此该方法不在身份验证范围内。

有很多不同的方法可以完成此任务。我能想到的最简单的方法是更改​​路线的后动作。像这样:

articles_viewset = UpdateArticleBodyViewSet.as_view({
    'post': 'update'
})

router.register(r'update-article', articles_viewset)

这样,您可以毫无问题地使用UpdateMixin。您可以根据需要调整update方法。