如何引发错误/返回{“foo”:[“此字段是必需的。”]} Django REST中的响应

时间:2015-09-04 15:26:08

标签: 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)

而不是返回“foo field required”。我想返回一条与Django REST返回相同的消息,例如: {“foo”:[“此字段为必填项。”]}

有更好的方法吗?也许用串行器单独验证foo字段?

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

Bar的模型是:

class Bar(models.Model):
    user = models.ForeignKey(User, db_index=True, editable=False)
    foo = models.ForeignKey(Foo, db_index=True)

3 个答案:

答案 0 :(得分:3)

是,

只需查看文档:{​​{3}}

我认为字段fooBar模型的一部分,如果不是,请将其添加到fields 中的Meta:< / p>

向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

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

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()

答案 1 :(得分:1)

是的,执行此操作的最佳方法是使用foo类中的extra_kwargs选项在序列化程序中生成Meta字段。

DRF将自动为您处理验证。您不需要自己提出此验证错误。

class Meta:
    ...
    extra_kwargs = {'foo': {'required':True}} # make 'foo' a required field.

现在,只要foo中未传递request字段,foo字典中就会有一个键serializer.errors,其值为{{1 }}

另外,创建一个This field is required.函数,该函数将验证validate_foo()的限制。

foo_object.counter

最终代码:

<强> serializers.py

def validate_foo(self, value):
    self.foo_object = get_object_or_404(Foo, pk=value) # get the 'foo' object
    if self.foo_object.counter == 10: # check for limits
        raise serializers.ValidationError('foo limit reached.') # raise error
    return value # must return the value at the end

<强> views.py

在您的观看中,您需要覆盖class BarSerializer(serializers.ModelSerializer): class Meta: ... extra_kwargs = {'foo': {'required':True}} # make 'foo' a required field. def validate_foo(self, value): self.foo_object = get_object_or_404(Foo, pk=value) if self.foo_object.counter == 10: raise serializers.ValidationError('foo limit reached.') return value 并将perform_create()user传递给serializer.foo_object函数。

serializer.save()

答案 2 :(得分:0)

您可以使用用户定义的消息

返回Response
if 'foo' not in self.request.data:
    return Response({"foo":["This field is required."]})