2010-11-05 82 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)