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

时间:2018-07-06 07:28:39

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

有一个模型:

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。 是否有可能重写模型的保存方法,以获得类似“在冲突(主机,端口)上插入...的行为,请更新设置登录名=登录名,密码=密码”。 Django 2,数据库-Postgres。

1 个答案:

答案 0 :(得分: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并进行更新,或者只是创建新的对象。