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

use*_*717 102 python django django-models

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

创建新人的代码如下:

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
Run Code Online (Sandbox Code Playgroud)

但我不知道在哪里检查并获取现有的人物对象.

Zag*_*ags 163

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

样品使用如下:

# 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}
)
Run Code Online (Sandbox Code Playgroud)

  • `update_or_create`的+1,因为对于那个用例,它比`get_or_create`更好,只是再次调用对象的`save()`. (9认同)

bak*_*kal 154

如果您正在寻找"更新如果存在其他创建"用例,请参阅@Zags优秀答案


Django已经有了get_or_create,https://docs.djangoproject.com/en/dev/ref/models/querysets/#get-or-create

对你来说可能是:

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
Run Code Online (Sandbox Code Playgroud)


Aam*_*nan 9

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
Run Code Online (Sandbox Code Playgroud)


And*_*röm 6

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)
Run Code Online (Sandbox Code Playgroud)

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

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