如何验证DRF中的更新字段? [英] How to validate a field on update in DRF?

查看:400
本文介绍了如何验证DRF中的更新字段?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带外键的模型的序列化器。要求是,在创建时,可以将外键设置为相关模型中的任何现有对象,但是在更新时,不能更改相关对象。我可以在自定义的 update()中进行检查,但是使用序列化程序验证来进行检查会更加优雅?但我不确定如何。示例代码:

I have a serializer for a model with a foreign key. The requirement is that on create, foreign key can be set to any existing object from the related model, but on update the related object cannot be changed. I can check this in the custom update(), but it would be more elegant to use serializer validation to check for this? But I am not sure how. Example code:

class Person(models.Model):
    name = models.CharField(max_length=256)
    spouse = models.ForeignKey(Person)

class PersonSerializer(serializers.ModelSerializer):
    class Meta:
        model = Person

    # this is how I know how to do this
    def create(self, validated_data):
        try:
            spouse = Person.objects.get(pk=int(validated_data.pop('spouse')))
        except Person.DoesNotExist:
            raise ValidationError('Imaginary spouses not allowed!')
        return Person.objects.create(spouse=spouse, **validation_data)

    def update(self, person, validated_data):
        if person.spouse.pk != int(validated_data['spouse']):
            raise ValidationError('Till death do us part!')
        person.name = validation_data.get('name', person.name)
        person.save()
        return person

   # the way I want to do this
   def validate_spouse(self, value):
       # do validation magic


推荐答案

您绝对可以使用对字段的验证来执行此操作。检查更新与创建的方式是检查验证功能中的 self.instance 。关于它有一些提及在序列化程序文档中

You can definitely do this using the validation on a field. The way you'd check if it's an update vs. creation is checking for self.instance in the validation function. There's a bit mentioned about it in the serializer documentation.

self.instance 将保存现有对象及其值,因此您可以使用它与之进行比较。

self.instance will hold the existing object and it's values, so you can then use it to compare against.

我相信这应该对您有用:

I believe this should work for your purposes:

def validate_spouse(self, value):
    if self.instance and value != self.instance.spouse:
        raise serializers.ValidationError("Till death do us part!")
    return value






另一种方法如果要更新的字段为read_only,则这样做会覆盖。这可以在序列化器的 __ init __ 中完成。与验证器类似,您只需查找一个实例并查看是否有数据:


Another way to do this is to override if the field is read_only if you're updating. This can be done in the __init__ of the serializer. Similar to the validator, you'd simply look for an instance and if there's data:

def __init__(self, *args, **kwargs):
    # Check if we're updating.
    updating = "instance" in kwargs and "data" in kwargs

    # Make sure the original initialization is done first.
    super().__init__(*args, **kwargs)

    # If we're updating, make the spouse field read only.
    if updating:
        self.fields['spouse'].read_only = True

这篇关于如何验证DRF中的更新字段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆