Django 视图集';的操作装饰程序正在忽略其权限\u类

Django 视图集';的操作装饰程序正在忽略其权限\u类,django,django-rest-framework,Django,Django Rest Framework,为什么我的action decorator忽略了它的permission\u类 我有一个视图集,该视图集对于一般发布/创建和发布到自定义操作装饰器都具有“IsAuthenticated” 但是,当我为未登录的用户使用自定义动作装饰器时,动作装饰器的代码仍在运行(并导致错误) 为什么会这样?非登录用户在发布到操作时不应该收到未经授权的401\u吗 未登录用户在执行一般post时确实会收到未经授权的401_ 以下是视图集: class ItemViewSet(viewsets.ModelViewSe

为什么我的action decorator忽略了它的permission\u类

我有一个视图集,该视图集对于一般发布/创建和发布到自定义操作装饰器都具有“IsAuthenticated”

但是,当我为未登录的用户使用自定义动作装饰器时,动作装饰器的代码仍在运行(并导致错误)

为什么会这样?非登录用户在发布到操作时不应该收到未经授权的401\u吗

未登录用户在执行一般post时确实会收到未经授权的401_

以下是视图集:

class ItemViewSet(viewsets.ModelViewSet):
    queryset = Item.objects.all()
    lookup_field = "pk"
    serializer_class = ItemSerializer

    def get_permissions(self):
        if self.action == "create":
            permission_classes = [IsAuthenticated]
        else:
            permission_classes = [AllowAny]
        return [permission() for permission in permission_classes]

    @action(
        methods=["post"],
        detail=True,
        permission_classes=[IsAuthenticated],
        url_name="actioned",
    )
    def actioned(self, request, pk=None):
        try:
            item = Item.objects.get(user=request.user)
            item.status = "actioned"
            item.save()
            return Response(status=status.HTTP_200_OK)
        except Item.DoesNotExist:
            Item.objects.create(user=request.user, status="actioned")
            return Response(status=status.HTTP_201_CREATED)
我正在对我的URL使用DefaultRouter():

router = DefaultRouter
router.register(r"items", ItemViewSet, basename="item")
urlpatterns = [ path("", include(router.urls)), ]
以下是测试:


# GENERIC POST BY ANONYMOUSUSER DOESN'T RUN AND GIVES 401
def test_public_generic_post(self):
    payload = {"status": None}
    response = APIClient.post(
        reverse("app:item-list"),
        payload,
        format="json"
    )
    self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) # True

# ACTION POST BY ANONYMOUSUSER RUNS EVEN THOUGH IT HAS THE SAME IsAuthenticated permission
def test_public_action_post(self):
    item = Item.objects.create()
    response = APIClient.post(
        reverse("app:item-actioned", args=[item.pk]),
        format="json"
    )
    self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) # False

对于action post,我收到以下错误:

TypeError:无法将AnonymousUser强制转换为int。是否尝试用它代替User?

因为它正在运行我的
try:item=item.objects.get(user=request.user)
code,并且没有
request.user

但是,如果动作装饰器显式地具有
权限_classes=[IsAuthenticated]
,它为什么要首先运行动作装饰器呢


根据@KutayAslan的评论,我可以确认
request.user.is\u authenticated
是否
False
,删除get\u permissions方法可以解决此错误

在我的原始代码中,由于其“self.action”属于“else”子句,动作装饰程序正在分配[AllowAny]

将permission_类设置为显式等于action decorator可解决此问题:

    def get_permissions(self):
        if self.action == "create":
            permission_classes = [IsAuthenticated]
        elif self.action == "actioned":
            permission_classes = [IsAuthenticated]
        else:
            permission_classes = [AllowAny]
        return [permission() for permission in permission_classes]

您是否尝试重命名用@action修饰的方法?因为ModelViewSet模型有一个名为action的变量,该变量指定当前操作的名称。@Tiki啊,是的,名为“action”的方法只是一个示例/伪代码。我已经在我原来的帖子中对它进行了重命名。我怀疑通过获取权限的方法,你能试着对它进行注释吗?@KutayAslan-yep,这修复了它,我知道我的错误现在为什么发生了。我将用答案更新此线程。谢谢