【问题标题】:How to validate a field on update in DRF?如何验证 DRF 中的更新字段?
【发布时间】:2017-01-28 15:25:45
【问题描述】:

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

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

【问题讨论】:

    标签: python django django-rest-framework


    【解决方案1】:

    您绝对可以使用字段验证来做到这一点。检查它是更新还是创建的方式是在验证函数中检查self.instance。有一点提到它in the serializer documentation

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

    我相信这应该适用于您的目的:

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

    另一种方法是在更新时覆盖该字段是否为只读。这可以在序列化器的__init__ 中完成。与验证器类似,您只需查找实例以及是否有数据:

    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
    

    【讨论】:

      猜你喜欢
      • 2021-07-30
      • 2022-08-10
      • 1970-01-01
      • 1970-01-01
      • 2019-02-19
      • 2021-01-16
      • 2020-07-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多