2010-11-05 65 views
15

如何传递包含字段以更新Django模型的字典? 这不是为了创建一个对象,而是为了更新它。通过kwargs更新模型django

例如:

obj = Object.objects.create(index=id, **fields) 

回答

25

只要PK是一样的,现有的行会被覆盖。

obj = Object(index=id, **fields) 
obj.save() 
+0

你的意思是它会创建如果在数据库中是没有字段与索引和更新,如果有字段与该索引?所以我们可以称它为update_or_create? – Pol 2010-11-05 17:27:58

+0

这是正确的。 – 2010-11-05 17:28:16

+0

哦,人!我已经完成了我的create_or_update方法...... Cose发现artikle,没有方法在django中创建或更新..有artikle:http://blog.roseman.org.uk/2010/03/9/easy-创建或更新/所以它的错误文章? – Pol 2010-11-05 17:31:06

11
def update_object(obj, **kwargs): 
    for k, v in kwargs.items(): 
     setattr(obj, k, v) 
    obj.save() 
+1

这可能不是什么OP希望,因为所有的字段将被写入到数据库;不只是那些'kwargs',所以可能会破坏事物。 1.5确实为'model.save'引入了'update_fields'参数,但是您必须重复字段名称。 – ded7 2013-12-15 08:37:25

8

你可以得到一个对象的查询集,然后更新此:

model = Model.objects.filter(pk=pk) 
model.update(**kwargs) 

这不会调用对象的.save()方法,虽然。但是,我认为它只会执行一个数据库查询。请注意,如果您没有过滤到一个对象(例如,查询有多个对象:例如您没有在PK上查询),它会更新所有对象。如果它筛选为无,则不会将任何内容写入数据库。

话虽如此,我并不知道伊格纳西奥的解决方案。我很喜欢那样。

+0

如果你设法得到多个记录,同时过滤PK,那么你有...更大的问题。尽管过滤为空也不是问题,因为可以发出不匹配任何记录的UPDATE查询。 – 2010-11-06 07:22:42

+0

是的,我的意思是如果你没有对PK进行查询,但是在其他被认为是唯一的东西上。 – 2010-11-06 07:39:59

3

如果你知道你要创建它:

Book.objects.create(**fields) 

假设你需要检查现有的实例,你可以用GET发现或创造:

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) 
+0

+1,因为它使用'defaults'和'setattr'来确保字段的内容应用于对象,而不会丢失可能已经在现有实例上设置的任何附加属性 – rhunwicks 2015-05-21 05:27:56

3

这个问题是有点老了,但只是到最近的Django的发展,使其达到日期 - 1.7以来一直存在的update_or_create方法在与get_or_create类似的查询集上。

在这种情况下,它可以像使用:

obj, created = Object.objects.update_or_create(index=id, defaults=fields)