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