Fab*_*bio 8 django-rest-framework
我想知道是否有可能使用action装饰器定义额外的参数:
class UserViewSet(viewsets.ModelViewSet):
"""
A viewset that provides the standard actions
"""
queryset = User.objects.all()
serializer_class = UserSerializer
@action(methods=['post'], detail=True)
def follow(self, request, pk=None):
user = self.get_object()
target_user = ???
Follow.objects.create(user=user, target=target_user)
return Response(status=status.HTTP_204_NO_CONTENT)
Run Code Online (Sandbox Code Playgroud)
我要实现的是匹配以下路径: api/users/{id}/follow/{target_id}
该follow操作将用于让ID为的用户id跟随另一个ID为的用户target_id。
更新:
由于似乎无法传递额外的参数,因此现在我将数据作为要遵循的用户ID列表发布:
用于验证数据的串行器:
class FollowSerializer(serializers.ModelSerializer):
user_ids = serializers.ListField(child=serializers.IntegerField(min_value=1), required=False, help_text='User target IDs')
Run Code Online (Sandbox Code Playgroud)
那个行动:
@action(detail=True, methods=['post'])
def follow(self, request, pk=None):
user = self.get_object()
serializer = FollowSerializer(data=request.data)
if serializer.is_valid():
serializer.data['user_ids']
for user_id in user_ids:
target_user = User.objects.get(pk=user_id)
Follow.objects.create(user=user, target=target_user)
return Response(status=status.HTTP_204_NO_CONTENT)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Run Code Online (Sandbox Code Playgroud)
我的解决方案存在的问题是,在自动生成的文档页面上,我看到带有UserSerializer字段的表单。
更新2:
以下技巧可让自动生成的文档页面显示正确的表单:
class UserViewSet(viewsets.ModelViewSet):
"""
A viewset that provides the standard actions
"""
queryset = User.objects.all()
def get_serializer_class(self):
if self.action == 'follow':
return FollowSerializer
else:
return UserSerializer
@action(methods=['post'], detail=True)
def follow(self, request, pk=None):
...
Run Code Online (Sandbox Code Playgroud)
JPG*_*JPG 10
您可以将target_idurl 传递为,api/users/{id}/follow/{target_id}但必须将视图更改为,
class UserViewSet(viewsets.ModelViewSet):
"""
A viewset that provides the standard actions
"""
queryset = User.objects.all()
serializer_class = UserSerializer
@action(methods=['post'], detail=True)
def follow(self, request, *args, **kwargs):
user = self.get_object()
target_user = int(kwargs['target_id'])
Follow.objects.create(user=user, target=target_user)
return Response(status=status.HTTP_204_NO_CONTENT)Run Code Online (Sandbox Code Playgroud)
并在urls.py中定义一个单独的内容path(),
urlpatterns = [
path('users/<int:pk>/follow/<int:target_id>/', UserViewSet.as_view({"post": "follow"}))
]
Run Code Online (Sandbox Code Playgroud)
Ahm*_*hab 10
事实上,您可以接受额外的 kwargs,如下 DRF 3.13.x,无需接触路由器,简洁的 DRF:
@action(detail=True, methods=['delete'], url_name='media-delete',
url_path='delete_media/(?P<media_pk>[^/.]+)')
def delete_media(self, request, pk=None, media_pk=None):
# do your logic
return Response({}, status=status.HTTP_202_ACCEPTED)
Run Code Online (Sandbox Code Playgroud)
这将自动覆盖默认路由器额外路由,以响应带有 ModelViewSet 注册路由的 @action 包装器。
我的解决方案存在的问题是,在自动生成的文档页面上,我看到带有UserSerializer字段的表单。
从文档中:
装饰器可以另外接受仅为路由视图设置的额外参数。例如:
这意味着任何可用作类属性的东西都可以用作的参数@action(),包括serializer_class:
@action(methods=['post'], detail=True, serializer_class=FollowSerializer)
def follow(self, request, pk=None):
# ...
serializer = self.get_serializer(data=request.data)
# ...
Run Code Online (Sandbox Code Playgroud)
这将导致正确的形式出现在自动生成的文档中。
| 归档时间: |
|
| 查看次数: |
6792 次 |
| 最近记录: |