django rest 框架 - 使用 detail_route 和 detail_list

django rest framework - using detail_route and detail_list

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

另外,我想要一个/users/registerURL可以POST 以注册新用户。

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)

几个问题:

谢谢!

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

def register(self, request):

根据 the documentation. Additionally 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 or in combination with django guardian 对象特定权限。

尤其是在使用 REST API 时,您最终会希望某些用户仅对某些对象执行操作,而不必对每个请求进行微观管理。对象级权限在这里很有用。

detail_route 和 detail_list 将在 DRF 3.0 上被弃用,而是使用 @action:

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

当此方法将说明由该端点表示的模型的单个实例时使用 detail=True,当它需要表示该模型的查询集时使用 False