Django模型更新或创建具有唯一约束的对象 [英] Django model update or create object with unique constraint

查看:364
本文介绍了Django模型更新或创建具有唯一约束的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有一个模型:

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、password=123。
然后我添加另一批代理,其中一个代理是相同的0.0.0.0:0000,但是新的login = 234和password = 234。
是否有可能重写模型的保存方法,以获得类似在冲突(主机,端口)上插入...的行为,请更新set login = login,password = password。
Django 2,数据库-Postgres。

I added batch of proxies in admin interface, and one of them is 0.0.0.0:0000, login=123, password=123. Then I add another batch of proxy, and one of them is the same 0.0.0.0:0000, but with new login=234 and password=234. Is any possibility to override save method of model to get behaviour like "insert ... on conflict (host, port) do update set login=login, password=password". Django 2, db - Postgres.

推荐答案

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

Finally I found answer by myself. If anyone need it here is it:

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

(1) Deactivate validate_unique on unique fields in model:

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

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

This check is called before save_model() or save() actions. So any other changes will be useless.

(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并对其进行更新,或者只是创建新对象。

No update_or_create() or something similar approaches does not work here because they lead to infinite recursion. Just update or save method (even with force_update option) does not work too, because current object have no id yet. So we need to get that id if such object exists and update it or just create new object.

这篇关于Django模型更新或创建具有唯一约束的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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