Python 创建 Django 模型或更新(如果存在)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14115318/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 10:31:25  来源:igfitidea点击:

Create Django model or update if exists

pythondjangodjango-models

提问by user1687717

I want to create a model object, like Person, if person's id doesn't not exist, or I will get that person object.

我想创建一个模型对象,比如 Person,如果 person 的 id 不存在,或者我会得到那个 person 对象。

The code to create a new person as following:

创建新人的代码如下:

class Person(models.Model):
    identifier = models.CharField(max_length = 10)
    name = models.CharField(max_length = 20)
    objects = PersonManager()

class PersonManager(models.Manager):
    def create_person(self, identifier):
        person = self.create(identifier = identifier)
        return person

But I don't know where to check and get the existing person object.

但我不知道在哪里检查和获取现有的人对象。

采纳答案by bakkal

If you're looking for "update if exists else create" use case, please refer to @Zags excellent answer

如果您正在寻找“如果存在则更新”用例,请参阅@Zags 优秀答案



Django already has a get_or_create, https://docs.djangoproject.com/en/dev/ref/models/querysets/#get-or-create

Django 已经有一个get_or_createhttps://docs.djangoproject.com/en/dev/ref/models/querysets/#get-or-create

For you it could be :

对你来说可能是:

id = 'some identifier'
person, created = Person.objects.get_or_create(identifier=id)

if created:
   # means you have created a new person
else:
   # person just refers to the existing one

回答by Aamir Adnan

Django has support for this, check get_or_create

Django 对此有支持,请检查get_or_create

person, created = Person.objects.get_or_create(name='abc')
if created:
    # A new person object created
else:
    # person object already exists

回答by Tom Manterfield

Thought I'd add an answer since your question title looks like it is asking how to create or update, rather than get or create as described in the question body.

我想我会添加一个答案,因为您的问题标题看起来像是在询问如何创建或更新,而不是按照问题正文中的描述获取或创建。

If you did want to create or update an object, the .save() method already has this behaviour by default, from the docs:

如果您确实想创建或更新对象,则 .save() 方法默认情况下已经具有此行为,来自文档

Django abstracts the need to use INSERT or UPDATE SQL statements. Specifically, when you call save(), Django follows this algorithm:

If the object's primary key attribute is set to a value that evaluates to True (i.e., a value other than None or the empty string), Django executes an UPDATE. If the object's primary key attribute is not set or if the UPDATE didn't update anything, Django executes an INSERT.

Django 抽象了使用 INSERT 或 UPDATE SQL 语句的需要。具体来说,当你调用 save() 时,Django 遵循这个算法:

如果对象的主键属性设置为计算结果为 True 的值(即,非 None 或空字符串的值),Django 将执行 UPDATE。如果对象的主键属性未设置或 UPDATE 未更新任何内容,Django 将执行 INSERT。

It's worth noting that when they say 'if the UPDATE didn't update anything' they are essentially referring to the case where the id you gave the object doesn't already exist in the database.

值得注意的是,当他们说“如果 UPDATE 没有更新任何内容”时,他们实际上是指您提供给对象的 id 在数据库中不存在的情况。

回答by Zags

It's unclear whether your question is asking for the get_or_createmethod (available from at least Django 1.3) or the update_or_createmethod (new in Django 1.7). It depends on how you want to update the user object.

不清楚您的问题是要求get_or_create方法(至少可从 Django 1.3 获得)还是update_or_create方法(Django 1.7 中的新方法)。这取决于您希望如何更新用户对象。

Sample use is as follows:

样例使用如下:

# In both cases, the call will get a person object with matching
# identifier or create one if none exists; if a person is created,
# it will be created with name equal to the value in `name`.

# In this case, if the Person already exists, its existing name is preserved
person, created = Person.objects.get_or_create(
        identifier=identifier, defaults={"name": name}
)

# In this case, if the Person already exists, its name is updated
person, created = Person.objects.update_or_create(
        identifier=identifier, defaults={"name": name}
)

回答by Aminah Nuraini

If one of the input when you create is a primary key, this will be enough:

如果创建时的输入之一是主键,这就足够了:

Person.objects.get_or_create(id=1)

It will automatically update if exist since two data with the same primary key is not allowed.

由于不允许具有相同主键的两个数据,如果存在,它将自动更新。

回答by Andreas Bergstr?m

For only a small amount of objects the update_or_createworks well, but if you're doing over a large collection it won't scale well. update_or_createalways first runs a SELECT and thereafter an UPDATE.

update_or_create仅适用于少量对象,但如果您正在处理大型集合,则无法很好地扩展。update_or_create总是首先运行 SELECT,然后运行 ​​UPDATE。

for the_bar in bars:
    updated_rows = SomeModel.objects.filter(bar=the_bar).update(foo=100)
        if not updated_rows:
            # if not exists, create new
            SomeModel.objects.create(bar=the_bar, foo=100)

This will at best only run the first update-query, and only if it matched zero rows run another INSERT-query. Which will greatly increase your performance if you expect most of the rows to actually be existing.

这最多只会运行第一个更新查询,并且只有当它匹配零行时才会运行另一个 INSERT 查询。如果您希望大多数行实际存在,这将大大提高您的性能。

It all comes down to your use case though. If you are expecting mostly inserts then perhaps the bulk_create()command could be an option.

不过,这一切都归结为您的用例。如果您期望大部分插入,那么也许bulk_create()命令可能是一个选项。