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

时间:2017-05-09 16:29:55

标签: django django-rest-framework

使用最新版本的Django和DRF。

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

假设我有一个有两个字段的模型。 field_bModelSerializer

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

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

关于field_c我想:

  1. 自定义验证它。就像我对其他两个领域一样。
  2. 要求整个请求必须成功,如果不成功,请发出“Field is required”错误,就像我忘记POST一个必需的模型字段一样。
  3. 有机会获取field_c并将其保存到数据库中完全不同的不相关模型行。
  4. 我似乎无法解决这个问题。如果我将fields添加到field_c元 - 它会抛出一个例外,说明validate_field_c不在我的模型中。如果我不在字段中包含它,我真正想要放在那里的clientSchema.post('save', function (client, next) { ClientProjection.update( {/* Query Parameters */}, {/* Data to update */}, function(err, clientProjection) { next() } }); 甚至都不会被调用。

    我该怎么办?

2 个答案:

答案 0 :(得分:5)

您可以在序列化程序中将自定义字段添加为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 :(得分:-1)

不要使用ModelSerializer - 使用重新创建与模型相同的字段的序列化程序&像你一样包括create()

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

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

在自定义document.querySelector("#myForm").addEventListener("submit", function (event) { event.preventDefault(); // ... Ajax call here ... }) 方法中,您可以根据需要创建模型实例或根据需要执行任何操作。