我想知道是否可以使用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)
我要实现的是匹配以下路径: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')
动作:
@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)
解决方案的问题在于,在自动生成的文档页面上,我看到带有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):
...
答案 0 :(得分:3)
您可以将wp_pagenavi()
作为url传递给target_id
,但必须将视图更改为,
api/users/{id}/follow/{target_id}
并在urls.py 中将 单独的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)
定义为
path()
答案 1 :(得分:3)
解决方案的问题是,在自动生成的文档页面上,我看到带有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)
# ...
这将导致正确的形式出现在自动生成的文档中。
答案 2 :(得分:0)
我不确定。查看文档,似乎@action()只会接受.get_extra_actions()获得的特定动作列表
您能否仅将目标的电子邮件地址/帐户名/帐户ID用作后续目标,然后发布该数据?无论如何,似乎这样做会更容易。