首页 文章

Django Rest Framework,ModelSerializers和自定义字段验证

提问于
浏览
1

使用最新版本的Django和DRF .

我有一个相当复杂的要求,我无法找到解决方案 . 我会尽力简化它 .

假设我有一个有两个字段的模型 . field_afield_b

我有一个 ModelSerializer . 我 POST 一个带有字段的请求 . 这些字段通过模型验证,然后对我的两个序列化函数 validate_field_avalidate_field_b 进行验证 . 一切都很好 .

现在我希望我的 POST 请求包含第三个不属于该模型成员的字段 . 我们称之为 field_c . 我的序列化程序中有一个自定义 def create(self, validated_data): ,它将所有内容保存到数据库中 .

关于 field_c 我想:

  • 自定义验证它 . 就像我对其他两个领域一样 .

  • 要求整个请求必须成功,如果不成功,则发出"Field is required"错误,就像我忘记POST一个必需的模型字段一样 .

  • 有机会获取 field_c 并将其保存到数据库中完全不同的不相关模型行 .

我似乎无法解决这个问题 . 如果我将 field_c 添加到 fields 元 - 它会抛出一个异常,说 field_c 不在我的模型中 . 如果我不将它包含在字段中,我真正想放在那里的 validate_field_c 甚至都没有被调用 .

我能做什么?

2 回答

  • 4

    您可以在序列化程序中将自定义字段添加为 write_only 字段并覆盖create方法,以便您可以处理自定义字段的值 .

    像这样的东西:

    class MySerializer(serializers.ModelSerializer):
        field_c = serializers.CharField(write_only=True)
    
        class Meta:
            model = MyModel
            fields = ('field_a', 'field_b', 'field_c')
    
        def validate_field_c(self, value):
            if value is 'test':
                raise ValidationError('Invalid')
            return value
    
        def create(self, validated_data, **kwargs):
            field_c = validated_data.pop('field_c')
    
            return MyModel.objects.create(**validated_data)
    
  • -1

    不要使用ModelSerializer - 使用重新创建与模型相同的字段的序列化程序并包含 field_c .

    我知道您希望您的模型在验证过程中完成一些工作,但DRF的设计使其能够隔离这些职责 . 你可以阅读更多关于它here . 基本上,序列化程序应该是完成所有验证繁重的程序 .

    当然,这意味着您必须在序列化程序中明确定义验证方法 .

    在自定义 create() 方法中,您可以根据需要创建模型实例或根据需要执行任何操作 .

相关问题