序列化程序验证功能不称为 DRF

sou*_*hah 8 python api django django-rest-framework

class ChildSerializer(serializers.ModelSerializer):


    class Meta:
         model = Child
         fields = '__all__'


class ParentSerializer(serializers.ModelSerializer):
    """
    Serializer for task
    """
    def validate_title(self, data):
        if not data.get('title'):
            raise serializers.ValidationError('Please set title')
        return data
Run Code Online (Sandbox Code Playgroud)

Post 时不调用验证函数,另外我如何向 ChildSerializer 提供自定义错误,

Ane*_*R S 5

您的 ParentSerializer 验证方法有一些问题。假设title您的模型中有一个字段ParentSerializer。对于字段级验证,您将获得字段而不是整个数据。也就是说,validate_title函数应该将title(数据的标题字段)作为参数而不是data。所以你不必data.get('title')检查title. 参考

class ParentSerializer(serializers.ModelSerializer):
    """
    Serializer for task
    """
    def validate_title(self, title):
        if not title:
            raise serializers.ValidationError('Please set title')
        return title
Run Code Online (Sandbox Code Playgroud)


sea*_*son 5

我遇到了一个类似的问题,我的自定义验证字段没有被调用。我写它是为了绕过不正确的 DRF 验证(更多细节如下所示,但不是答案所必需的)。

查看 DRF 源代码,我发现了我的问题:DRF 始终使用其代码验证您的字段,然后再使用您的自定义代码进行验证。

''' rest-framework/serializers.py '''

for field in fields:
    validate_method = getattr(self, 'validate_' + field.field_name, None)
    primitive_value = field.get_value(data)
    try:
        # DRF validation always runs first!
        # If DRF validator throws, then custom validation is not called
        validated_value = field.run_validation(primitive_value)
        if validate_method is not None:
            # this is your custom validation
            validated_value = validate_method(validated_value)
    except ValidationError as exc:
        errors[field.field_name] = exc.detail
    except DjangoValidationError as exc:
        errors[field.field_name] = get_error_detail(exc)
Run Code Online (Sandbox Code Playgroud)

答:自定义验证器不能用于绕过 DRF 的验证器,因为它们将始终首先运行,并会在您说它有效之前引发异常。

(对于那些感兴趣的人,我遇到的验证错误是这样的:用于 ModelA 的 ModelSerializer,它与 ModelB 有 OneToOne 关系。ModelB 有一个 UUID 用于它的 pk。DRF'53abb068-0286-411e-8729-0174635c5d81' is not a valid UUID.在验证时抛出错误,这是不正确的,真的很令人气愤。 )