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

时间:2013-01-01 23:43:23

标签: 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

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

8 个答案:

答案 0 :(得分:140)

如果您正在寻找“更新,如果存在其他创建”用例,请参阅@Zags excellent answer


Django已经有get_or_createhttps://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

答案 1 :(得分:134)

目前还不清楚您的问题是询问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}
)

答案 2 :(得分:8)

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

答案 3 :(得分:3)

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

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

  

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

     

如果对象的主键属性设置为计算值   Django为True(即除None或空字符串以外的值)   执行更新。如果未设置对象的主键属性   或者如果UPDATE没有更新任何内容,Django会执行INSERT。

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

答案 4 :(得分:1)

如果您创建的其中一个输入是主键,这就足够了:

<body ng-app="crud">
  <div ng-controller="ctrl">       
    <div>
      <table>
        <tr ng-repeat="x in data track by $index">
          <td>{{x}}</td>
          <td>{{$index}}</td>
        </tr> 
      </table>
    </div>
  </div>
</body>

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

答案 5 :(得分:1)

对于仅少量对象, 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)

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

这一切都取决于您的用例。如果您期望插入大部分内容,那么可以使用bulk_create()命令。

答案 6 :(得分:0)

这应该是您要寻找的答案

EmployeeInfo.objects.update_or_create(
    #id or any primary key:value to search for
    identifier=your_id, 
    #if found update with the following or save/create if not found
    defaults={'name':'your_name'}
)

答案 7 :(得分:0)

您也可以像使用get_or_create一样使用update_or_create,这是我为update_or_create遵循的模式,其中假设一个具有ID(关键字),姓名,年龄,is_manager作为属性的人-

update_values = {"is_manager": False}
new_values = {"name": "Bob", "age": 25, "is_manager":True}

obj, created = Person.objects.update_or_create(identifier='proficiency',
                                               defaults=update_values)
if created:
    obj.update(**new_values)