假设我有以下序列化器:
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_text
或validate
或QuestionSerializer
中的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
被传递给该字段,而该字段要求是true
或false
,那么该字段应该传递什么值?字符串tralse
?
另一个字段验证器可以简单地要求该字段是请求的一部分。因此,这意味着如果该字段验证器失败,则该字段根本没有值。因此,唯一合理的做法可能是从validated_data
字典中省略它,但是validate
方法将所有必需字段都在validated_data
字典中作为先决条件。因此,在这些数据上运行validate
也是没有意义的。