django rest框架:从多个验证中合并ValidationError



假设我有以下序列化器:

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,则QuestionSerializer中的validate不会运行。因此,我无法解释POST数据的所有问题。

是否有一种方法可以运行一个序列化器的validate函数,即使它的一个字段验证器或子序列化器验证失败,然后合并所有错误?

我已经尝试了以下,但没有成功,使其正常工作。它确实运行验证函数和其他验证器,但你不能嵌套AllErrorSerializer,更重要的是,当你没有错误时,它不起作用:你不能保存实例,因为你有inspect 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)

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

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

例如,你的序列化器可能有一个布尔字段。例如,如果一个值tralse被传递给该字段,而该字段要求是truefalse,那么该字段应该传递什么值?字符串tralse?

另一个字段验证器可以简单地要求该字段是请求的一部分。因此,这意味着如果该字段验证器失败,则该字段根本没有值。因此,唯一合理的做法可能是从validated_data字典中省略它,但是validate方法将所有必需字段都在validated_data字典中作为先决条件。因此,在这些数据上运行validate也是没有意义的。

最新更新