我想创建一个模型对象,比如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
但我不知道在哪里检查并获取现有的人物对象。
答案 0 :(得分:140)
如果您正在寻找“更新,如果存在其他创建”用例,请参阅@Zags excellent answer
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
答案 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)