django rest framework - 使用detail_route和detail_list

Ofe*_*mon 10 python django routing django-rest-framework

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

另外,我希望有一个/ users/register URL我可以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)
Run Code Online (Sandbox Code Playgroud)

几个问题:

  • 这是正确的做法吗?

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

谢谢!

Seb*_*zny 13

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

def register(self, request):
Run Code Online (Sandbox Code Playgroud)

根据文档,这是正确的签名.此外,测试表明不可能为路由传递额外的参数,并且pk将始终传递给a @detail_route,因此您必须具有:

@detail_route
def register(self, request, pk=None):
Run Code Online (Sandbox Code Playgroud)

详细路线和

@list_route
def register(self, request):
Run Code Online (Sandbox Code Playgroud)

列表路线.

但是我建议您利用内置的ViewSetMixins,因为ModelViewSet在内部执行:

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)
Run Code Online (Sandbox Code Playgroud)

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

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

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


Gre*_*ory 5

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

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

当此方法将说明该端点表示的Model的单个实例时,请使用detail = True;当它需要表示该模型的Queryset时,请使用False。

  • 这是文档:https://www.django-rest-framework.org/community/3.8-announcement/#deprecations (2认同)