如何在 Django REST 中引发错误/返回 {"foo":["This field is required."]} 响应

gor*_*vix 6 python django django-rest-framework

假设我有一个视图,我需要在调用 serializer.save 之前检查是否给出了一个字段,以确保我没有收到字典键错误:

class BarView(CreateAPIView):
    serializer_class = BarSerializer
    queryset = Bar.objects.all()
    def perform_create(self, serializer):
        if 'foo' not in self.request.data:
            raise ParseError('foo field required.')
        foo = get_object_or_404(Foo, pk=self.request.data['foo'])
        if foo.counter == 10:
            raise ParseError('foo limit reached.')
        return serializer.save(user=self.request.user, foo=foo)
Run Code Online (Sandbox Code Playgroud)

而不是返回的"foo field required."我想返回的消息一样Django的REST返回如{"foo":["This field is required."]}

有一个更好的方法吗?也许使用序列化程序单独验证 foo 字段?

更新:我忘了提到用户字段也是必需的。

Bar 的模型是:

class Bar(models.Model):
    user = models.ForeignKey(User, db_index=True, editable=False)
    foo = models.ForeignKey(Foo, db_index=True)
Run Code Online (Sandbox Code Playgroud)

WBA*_*BAR 6

是的,

只需查看文档:验证

我假设该字段fooBar模型的一部分,如果不是,请将其添加到fieldsinMeta):

向 BarSerializer 添加验证:

class BarSerializer(serializers.ModelSerializer):
    def validate_foo(self, value):
        if not value:
            raise serializers.ValidationError("foo field required.")
        if Foo.objects.filter(pk=value, counter__gte=10).exists():
            raise serializers.ValidationError("foo limit reached.")
        return value

    class Meta:
        model = Bar
Run Code Online (Sandbox Code Playgroud)

然后通过扩展这个来创建你的视图:

from rest_framework.exceptions import ValidationError

class MyCreateAPIView(CreateAPIView):        
    def post(self, request, *args, **kwargs):
        try:
             return super(BarView, self).post(request, *args, **kwargs)
        except ValidationError as e:
             return Response(e.detail, , status=status.HTTP_400_BAD_REQUEST)

    def create(self,request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        try:
            self.perform_create(serializer)       
        except DjangoValidationError as e:
            raise ValidationError(e.messages)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

    def perform_create(serializer):
        # do your stuff
        serializer.save()
Run Code Online (Sandbox Code Playgroud)


Vis*_*yay 0

您可以返回Response用户定义的消息

if 'foo' not in self.request.data:
    return Response({"foo":["This field is required."]})
Run Code Online (Sandbox Code Playgroud)