【发布时间】:2011-05-05 17:28:44
【问题描述】:
如何传递包含字段的字典来更新 Django 模型? 这不是创建对象,而是更新对象。
示例:
obj = Object.objects.create(index=id, **fields)
【问题讨论】:
如何传递包含字段的字典来更新 Django 模型? 这不是创建对象,而是更新对象。
示例:
obj = Object.objects.create(index=id, **fields)
【问题讨论】:
只要PK相同,就会覆盖现有行。
obj = Object(index=id, **fields)
obj.save()
【讨论】:
fields 中指定的字段,obj 将被Object 的新实例的默认值覆盖。
def update_object(obj, **kwargs):
for k, v in kwargs.items():
setattr(obj, k, v)
obj.save()
【讨论】:
kwargs 中的那些,所以可能会破坏一些东西。 1.5 确实向model.save 引入了update_fields 参数,尽管您必须重复字段名称。
你可以得到一个对象的查询集,然后更新这个:
model = Model.objects.filter(pk=pk)
model.update(**kwargs)
不过,这不会调用对象的 .save() 方法。但是,我认为它只会执行一次数据库查询。
请注意,如果您没有过滤到一个对象(即,查询有多个对象:例如,如果您没有在 PK 上进行查询),它将更新所有对象。如果它过滤为无,则不会将任何内容写入数据库。
话虽如此,我并不知道 Ignacio 的解决方案。我很喜欢。
【讨论】:
UPDATE 查询是有效的。
如果您知道要创建它:
Book.objects.create(**fields)
假设您需要检查现有实例,您可以使用 get 或 create 找到它:
instance, created = Book.objects.get_or_create(slug=slug, defaults=fields)
if not created:
for attr, value in fields.iteritems():
setattr(instance, attr, value)
instance.save()
正如另一个答案中提到的,您还可以在查询集管理器上使用 update 函数,但我相信这不会发出任何信号(如果您不使用它们,这对您来说可能无关紧要)。但是,您可能不应该使用它来更改单个对象:
Book.objects.filter(id=id).update(**fields)
【讨论】:
defaults 和setattr 来确保将字段的内容应用于对象,而不会丢失可能已经在现有实例上设置的任何其他属性
这个问题有点老了,但只是为了让它与最近的 Django 发展保持同步 - 从 1.7 开始,查询集上有一个 update_or_create 方法,其工作方式类似于 get_or_create。
在这种情况下,它可以像这样使用:
obj, created = Object.objects.update_or_create(index=id, defaults={**fields})
【讨论】:
您可以在filter()查询之后使用方法简单地更新
obj = Object.objects.filter(index=id).update(**fields) # fields your object(dict) may be **kwargs
如果它是一个 .get() 方法,
obj = Object.objects.get(index=id)
obj['key1'] = 'value1'
obj.save()
【讨论】: