我在User
模型上构建了非常基本的 ViewSet 来欺骗用户。
ModelViewSet
和@action
装饰器来使代码整洁。IsAuthenticated
函数所需的权限(仅以list
为例)。这样只有签署的人才能这样做。 这是代码示例。
from rest_framework.decorators import action, list_route
from rest_framework.permissions import IsAuthenticated
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
@action(detail=False, permission_classes=[IsAuthenticated])
def list(self, request, *args, **kwargs):
return super(UserViewSet, self).list(request, *args, **kwargs)
但是我遇到了错误
不能在以下方法上使用@action装饰器,因为它们是现有路由:list
如果我删除@action
,它将很好地工作。我的问题是为什么我不能在现有路由list
上使用@action装饰器?
答案 0 :(得分:2)
@action
用于“额外动作”,实际上意味着(如果您检查代码):“未在路由器中明确定义”。因此,如果您使用DefaultRouter
或SimpleRouter
在URL中注册视图,则路由器将抛出此错误。
对于您的情况,您可以修改View.get_permissions
,如docs example所示:
from rest_framework.permissions import IsAuthenticated
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
def get_permissions(self):
if self.action == 'list':
return [IsAuthenticated()]
else:
return super(self, UserViewSet).get_permissions()
答案 1 :(得分:0)
即使它不能回答该用户的特定问题,我也要张贴任何误导性标题后到达的人,您可以使用@action装饰符作为{{1} }
如下定义视图集:
ModelViewSet
定义路由器和API
from rest_framework import viewsets
class MyModelViewSet(viewsets.ModelViewSet):
serializer_class = MyModelSerializer
queryset = MyModel.objects.all()
@action(detail=True, methods=['get'], url_path='my-action')
def my_action(self, request, *args, **kwargs):
""" Get last property-run and return associated results """
instance = self.get_object()
# custom code
custom_response = {"test": "hello world"}
return Response(custom_response, status=status.HTTP_200_OK)
然后只需通过from rest_framework import routers
from django.conf.urls import url
router = routers.SimpleRouter()
router.register(r'mymodel', MyModelViewSet)
urlpatterns += [
url(r'^api/1/', include(router.urls))
]
答案 2 :(得分:0)