django rest framework - 使用detail_route和detail_list

时间:2015-05-23 08:07:05

标签: python django routing django-rest-framework

在我的代码中,我有一个用户的视图集。 我想要的是只允许ReadOnlyModelViewSet做的Read操作( / users / 42 / users / )。

此外,我想要一个 / users / register 网址,我可以发布以注册新用户。

class UserViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer

    @list_route(methods=['post'])
    def register(request):
        serializer = UserSerializer(data=request.DATA)
        if serializer.is_valid():
            user = User.objects.create_user(
                username = serializer.init_data['username'],
                password = serializer.init_data['password'],
            )

            return Response(serializer.data, status=status.HTTP_201_CREATED)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

几个问题:

  • 这是正确的做法吗?

  • 如果我将方法放在 list_route detail_route 装饰器中,是否有特定的签名?因为在detail_route示例中,它始终与方法的签名相同: method_name (self,request,pk = None):

谢谢!

2 个答案:

答案 0 :(得分:13)

您的代码几乎是正确的,您只是在注册方法上错过了正确的签名:

def register(self, request):

根据the documentation,这是正确的签名。另外the tests表示无法为路由传递其他参数,并且pk将始终为@detail_route传递,因此您必须拥有:

@detail_route
def register(self, request, pk=None):

详细路线和

@list_route
def register(self, request):

列表路线。

但我建议你利用内置的ViewSetMixins as ModelViewSet does internally

from rest_framework import exceptions, mixins
class UserViewSet(mixins.CreateModelMixin,
               mixins.RetrieveModelMixin,
               mixins.ListModelMixin,
               GenericViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    def create(self, request):
        serializer = UserSerializer(data=request.DATA)
            if serializer.is_valid():
                user = User.objects.create_user(
                    username = serializer.init_data['username'],
                    password = serializer.init_data['password'],
                )

                return Response(serializer.data, status=status.HTTP_201_CREATED)
            else:
                return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

对于一般用户注册,您还可以查看我正在为我的项目工作的django-registration-restframework

我个人在项目中依赖ModelViewSet,并确保只有经过适当授权的用户才能执行某些操作。为此,您可以使用模型范围permissions或与django guardian对象特定权限相结合。

特别是使用REST API,您最终会发现您希望某些用户仅对某些对象执行操作,而无需对每个请求进行微观管理。对象级权限在这里非常有用。

答案 1 :(得分:2)

detail_route和detail_list将在DRF 3.0上弃用,请改用@action:

from rest_framework.decorators import action
    @action(methods=['POST'], detail=True)
    def sale(self):
       ...

使用detail = True表示此方法将说明该终结点表示的Model的单个实例,而当需要表示该模型的Queryset时表示False