我被迫写一些杂乱的工作,我需要创建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上已经有几个问题,但是没有一个提供答案。在这种情况下,有什么方法可以使用路由器吗?还是我被迫明确地编写网址?
答案 0 :(得分:0)
这里的问题是,您要从其继承的两个类都没有一个post
方法,因此您实际上并没有覆盖它。因此该方法不在身份验证范围内。
有很多不同的方法可以完成此任务。我能想到的最简单的方法是更改路线的后动作。像这样:
articles_viewset = UpdateArticleBodyViewSet.as_view({
'post': 'update'
})
router.register(r'update-article', articles_viewset)
这样,您可以毫无问题地使用UpdateMixin
。您可以根据需要调整update
方法。