我有以下代码(针对端点/东西/ {id} / permission-to-do / 的 views.py
class PermissionsToDo(APIView):
authentication_classes = (TokenAuthentication,)
permission_classes = (IsAuthenticated,)
def get(self, request,*args,**kwargs):
thing_id = kwargs.get('pk')
thing = Thing.objects.filter(pk=thing_id,is_active=True)
serializer = serializers.GetDoPermissionSerializer(thing[0],context={'request': request})
return Response(serializer.data, status=status.HTTP_200_OK)
serializers.py
class serializers.GetDoPermissionSerializer(serializers.ModelSerializer):
def _can_do(self, thing):
return thing.can_be_done_by(self.context['request'].user)
can_do = serializers.SerializerMethodField('_can_do')
class Meta:
model = Thing.objects.filter
fields = ('can_do',)
extra_kwargs = {
'can_do': {'read_only': True},
}
thing.can_be_done_by(user)
方法返回一个布尔值。这适用于正确的请求,但我想添加一种方法来验证请求并发送适当的客户端错误状态代码,例如status.HTTP_400_BAD_REQUEST
我的想法只是添加 views.py a:
if serializer.is_valid():
return Response(serializer.data, status=status.HTTP_200_OK)
else:
return Response(SOMETHING?,status.HTTP_400_BAD_REQUEST)
如果我评估serializer.is_valid()
,我会收到一条错误消息:
'Cannot call `.is_valid()` as no `data=` keyword argument was '
AssertionError: Cannot call `.is_valid()` as no `data=` keyword argument was passed when instantiating the serializer instance.
如果我换行:
serializer = serializers.GetDoPermissionSerializer(thing[0],context={'request': request})
成:
serializer = serializers.GetDoPermissionSerializer(data=thing[0],context={'request': request})
然后,我得到一个错误,表明我应该将字典作为数据而不是对象传递。但后来我不确定如何实现validate
方法以及如何更改_can_do
方法以使其正常工作。
有什么想法吗?
感谢你的时间,如果你有空的话!
答案 0 :(得分:1)
.validate()
方法接受一个参数,该参数是字段值的字典。如有必要,它应该引发ValidationError,或者只返回经过验证的值
其中一种方法是将model object
转换为dict
。因此,请尝试以下代码段,
class PermissionsToDo(APIView):
authentication_classes = (TokenAuthentication,)
permission_classes = (IsAuthenticated,)
def get(self, request, *args, **kwargs):
thing_id = kwargs.get('pk')
thing = Thing.objects.filter(pk=thing_id, is_active=True)
serializer = serializers.GetDoPermissionSerializer(data=thing[0].__dict__, context={'request': request}) # Change is here <<<<
if serializer.is_valid():
return Response(serializer.data, status=status.HTTP_200_OK)
return Response(SOMETHING?, status.HTTP_400_BAD_REQUEST)
我的建议
如果要从DB序列化对象,大多数情况下它不会引发任何验证错误。我建议,如果thing
对象变为empty queryset
,请尝试显示错误消息。所以,
class PermissionsToDo(APIView):
authentication_classes = (TokenAuthentication,)
permission_classes = (IsAuthenticated,)
def get(self, request, *args, **kwargs):
thing_id = kwargs.get('pk')
try:
serializer = serializers.GetDoPermissionSerializer(Thing.objects.get(id=thing_id), context={'request': request})
return Response(serializer.data, status=status.HTTP_200_OK)
except Thing.DoesNotExist:
return Response(data="object not found", status.HTTP_400_BAD_REQUEST)
答案 1 :(得分:0)
我使用了你的建议&#34;除了我必须修改最后一行。我换了:
return Response(data="object not found", status.HTTP_400_BAD_REQUEST)
by:
return Response("object not found", status.HTTP_400_BAD_REQUEST)
或者我收到以下错误:
SyntaxError: positional argument follows keyword argument