python - 如何验证 DRF 中的更新字段?

标签 python django django-rest-framework

我有一个带有外键的模型序列化器。要求是在创建时,外键可以设置为相关模型中的任何现有对象,但在更新时不能更改相关对象。我可以在自定义 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

最佳答案

您绝对可以使用字段验证来做到这一点。检查它是更新还是创建的方法是在验证函数中检查 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

执行此操作的另一种方法是在更新时覆盖字段是否为 read_only。这可以在序列化程序的 __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

关于python - 如何验证 DRF 中的更新字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39598576/

相关文章:

python - 需要对部分正则表达式代码的具体解释

python - 如何将数据帧行转换为一组对?

Python3+Django1.10+mysqlclient1.3.9 : cannot save emoji characters

python - DRF json 404 而不是 html 页面

python - Django REST框架: how to properly use the HyperlinkedModelSerializer url field in unit tests

reactjs - 从 React 前端使用 DRF 上传图像

python - 如何使用 SSH key 通过 Paramiko 连接到 SFTP - Pageant

python - AWS - DJANGO - 格式化错误 : OperationalError: fe_sendauth: no password supplied

python - 我需要更新特定用户 Django 的图像

python - 在 IBM Watson 中部署笔记本