【问题标题】:django rest framweork: combine ValidationError from multiple validationdjango rest框架:组合来自多个验证的验证错误
【发布时间】:2021-12-13 18:54:26
【问题描述】:

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

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

如果AnswerSerializer 中的validate_answer_textvalidateQuestionSerializer 中的validate_question_text 引发ValidationError,则QuestionSerializervalidate 将不会运行。因此,我无法解释 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)
    

【问题讨论】:

  • 如果其中一个字段验证器引发异常,则无法构造 validated_data 字典以运行 validate,因为这要求所有字段都单独有效,这就是为什么它不运行validate 方法。

标签: django django-rest-framework django-serializer validationerror


【解决方案1】:

当某个字段无效时运行验证是没有意义的。 Django 将首先验证各个字段,然后构造一个包含经过验证的数据的字典,从而使用经过验证的数据运行 .validate(…) 方法。

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

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

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

【讨论】:

    猜你喜欢
    • 2019-03-16
    • 1970-01-01
    • 2015-08-16
    • 1970-01-01
    • 2017-11-29
    • 1970-01-01
    • 2013-06-29
    • 2017-09-26
    • 2017-11-02
    相关资源
    最近更新 更多