Skip to main content
 首页 » 编程设计

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

2024年09月07日37TianFang

有一个模型:

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,但新登录名=234 和密码=234。 是否有可能覆盖模型的保存方法以获得类似“插入...冲突(主机,端口)做更新设置登录名=登录名,密码=密码”的行为。 Django 2,db - Postgres。

请您参考如下方法:

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

(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 并更新它或创建新对象。