Django model update or create object with unique constraint

时光毁灭记忆、已成空白 提交于 2020-01-24 16:50:51

问题


There is a model:

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")

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.


回答1:


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

(1) Deactivate validate_unique on unique fields in model:

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

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

(2) Override save method:

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)

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.



来源:https://stackoverflow.com/questions/51205137/django-model-update-or-create-object-with-unique-constraint

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!