有一个模型:
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。
答案 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并进行更新,或者只是创建新的对象。