【问题标题】:Django model update or create object with unique constraintDjango 模型更新或创建具有唯一约束的对象
【发布时间】:2018-07-12 15:27:59
【问题描述】:

有一个模型:

class Proxy(models.Model):
        host = models.CharField(max_length=100,)
        port = models.CharField(max_length=10,)
        login = models.CharField(max_length=100,)
        password = models.CharField(max_length=100,)
    class Meta:
        unique_together = ("host", "port")

我在管理界面添加了一批代理,其中一个是 0.0.0.0:0000,登录=123,密码=123。 然后我添加了另一批代理,其中一个是相同的 0.0.0.0:0000,但新的登录名=234,密码=234。 是否有可能覆盖模型的保存方法以获得类似“插入......冲突(主机,端口)更新设置登录=登录,密码=密码”之类的行为。 Django 2,数据库 - Postgres。

【问题讨论】:

    标签: python django web-services django-models django-admin


    【解决方案1】:

    最后我自己找到了答案。如果有人需要,就在这里:

    (1) 停用模型中唯一字段的 validate_unique:

    def validate_unique(self, exclude=None):
        super().validate_unique(exclude='host')
    

    此检查在 save_model() 或 save() 操作之前调用。因此,任何其他更改都将毫无用处。

    (2) 覆盖保存方法:

    def save(self, *args, **kwargs):
        proxy = Proxy.objects.get(host=self.host, port=self.port)
        if proxy:
            self.id = proxy.id
            super().save(*args, **kwargs, update_fields=["login", "password"])
        else:
            super().save(*args, **kwargs)
    

    没有 update_or_create() 或类似的方法在这里不起作用,因为它们会导致无限递归。仅更新或保存方法(即使使用 force_update 选项)也不起作用,因为当前对象还没有 id。因此,如果此类对象存在,我们需要获取该 id 并更新它或创建新对象。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-19
      • 2011-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-04
      • 2017-03-27
      • 2021-09-05
      相关资源
      最近更新 更多