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)
几个问题:
这是正确的做法吗?
如果我将方法放在 list_route 中,是否有特定的 signature 或detail_route 装饰器?因为在 detail_route 示例中,方法的签名始终相同:method_name(self, request, pk=None):
谢谢!
您的代码几乎是正确的,只是在注册方法上缺少正确的签名:
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
在我的代码中,我有一个用户视图集。 我想要的是只允许读取操作(/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)
几个问题:
这是正确的做法吗?
如果我将方法放在 list_route 中,是否有特定的 signature 或detail_route 装饰器?因为在 detail_route 示例中,方法的签名始终相同:method_name(self, request, pk=None):
谢谢!
您的代码几乎是正确的,只是在注册方法上缺少正确的签名:
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