Django模型更新或创建具有唯一约束的对象

python django web-services django-models django-admin

436 观看

1回复

16 作者的声誉

有一个模型:

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,login = 123,密码= 123。然后我添加另一批代理,其中一个是相同的0.0.0.0:0000,但新的login = 234和密码= 234。是否有可能覆盖模型的保存方法以获得“插入...在冲突(主机,端口)上执行更新设置登录=登录,密码=密码”等行为。Django 2,db - Postgres。

作者: Egor Pleshakov 的来源 发布者: 2018 年 7 月 6 日

回应 1


1

16 作者的声誉

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

(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,如果这样的对象存在并更新它或只是创建新对象。

作者: Egor Pleshakov 发布者: 2018 年 7 月 12 日
32x32