django rest framework:结合来自多个验证的ValidationError

django rest framweork: combine ValidationError from multiple validation

假设我有以下序列化程序:

class AnswerSerializer(ModelSerializer):
    answer_text=CharField()

    def validate_answer_text(self, value):
        ...
        return value

    def validate(self, value):
        ...
        return value

class QuestionSerializer(ModelSerializer):
    question_text=CharField()
    answer=AnswerSerializer(many=True, read_only=False)

    def validate_question_text(self, value):
        ...
        return value

    def validate(self, value):
        ...
        return value

如果 validate_answer_text or validate in AnswerSerializer or validate_question_text in QuestionSerializer raise a ValidationError, the validate of QuestionSerializer 不会是 运行。因此,我无法解释 POST 数据的所有问题。

有没有办法 运行 序列化器的 validate 函数,即使其中一个字段验证器或子序列化器验证失败,然后合并所有错误?

我试过following但没有成功使它正常工作。它确实 运行 验证函数和其他验证器,但你不能嵌套 AllErrorSerializer 更重要的是,当你没有错误时它不起作用:你无法保存实例因为你已经检查 serializer.data.

编辑

由于 Willem Van Onsem 的回答,我最终得到以下解决方案:

#serializers.py
class AnswerSerializer(ModelSerializer):
    answer_text=CharField()

    class Meta:
        model=Answer
        ...

    def validate_answer_text(self, value):
        ...
        return value

    def validate(self, value):
        ...
        return value

class QuestionSerializer(ModelSerializer):
    question_text=CharField()
    answer=AnswerSerializer(many=True, read_only=False)
    class Meta:
        model=Question
        ...

    def validate_question_text(self, value):
        ...
        return value

class BasicAnswerSerializer(ModelSerializer):
    answer_text=CharField()

    class Meta:
        model=Answer
        ...

class BusinessRuleValidator(ModelSerializer):
    question_text=CharField()
    answer=BasicAnswerSerializer(many=True, read_only=False)

    class Meta:
        model=Question
        ...

    def validate(self, value):
        ...
        return value

#views.py

class QuestionViewSet(ModelViewSet):
...
    def create(self, request):
        validator = BusinessRuleValidator(data=request.data)
        validator.is_valid()
        serializer = QuestionSerializer(data=request.data)
        serializer.is_valid()
        if (len(validator.errors) or len(serializer.errors)):
            return Response(merge(validators.errors, serializer.errors), status=404)
        serializer.create()
        return Response('created', status=201)
    

运行 验证哪些字段无效是没有意义的。 Django 将首先验证各个字段,然后构造一个包含验证数据的字典,因此 运行 .validate(…) 方法包含验证数据。

但是由于(至少)其中一个字段的数据是无效的,因此意味着我们不能在有效数据的情况下构造这样的字典,因此 .validate(…) 方法的前提条件不再成立.为了解决这个问题,首先这些字段应该可用。

例如,您的序列化程序可能有一个布尔字段。例如,如果将值 tralse 传递给该字段,并且该字段需要为 truefalse,那么应该为该字段传递什么值?随机布尔值,字符串 tralse?

另一个字段验证器可以简单地要求该字段是请求的一部分。因此,这意味着如果该字段验证器失败,则该字段根本就没有价值。因此,唯一明智的做法可能是从 validated_data 字典中省略它,但 validate 方法以所有必填字段都在 validated_data 字典中为前提。因此,运行 validate 在该数据上再次毫无意义。