2009-10-16 62 views
43

我想知道,在Django中更新模型實例的多個字段的標準方式是什麼? ......如果我有一些領域的典範,如何更新django模型實例的多個字段?

Class foomodel(models.Model): 
    field1 = models.CharField(max_length=10) 
    field2 = models.CharField(max_length=10) 
    field3 = models.CharField(max_length=10) 
    ... 

...我有一個字段初始化它給出的,然後在單獨的步驟我想提供的字段的其餘部分,我該怎麼辦通過傳遞字典或鍵值參數來做到這一點?可能?

換句話說,我有一個包含一些數據的字典,其中包含我想要寫入該模型實例的所有內容。模型實例已經在一個單獨的步驟中被實例化,並且假設它還沒有被持久化。對於每個字段,我可以說是foo_instance.field1 = my_data_dict['field1'],但是有些東西告訴我應該有一種方法在模型實例上調用一個方法,我只需一次傳遞所有的字段值對並更新它們。類似foo_instance.update(my_data_dict)。我沒有看到任何像這樣的內置方法,我是否錯過了它,或者如何有效地完成它?

我有一種感覺,這是一個明顯的,RTM類型的問題,但我只是沒有看到它在文檔中。

回答

93

人們很容易與__dict__一塌糊塗,但不適用於從父類繼承的屬性。

您可以遍歷分配給對象的字典:

for (key, value) in my_data_dict.items(): 
    setattr(obj, key, value) 

或者你也可以直接從一個QuerySet修改(確保你的查詢只設置返回你感興趣的對象):

FooModel.objects.filter(whatever="anything").update(**my_data_dict) 
+0

這是否與m2m領域的工作? – 2016-05-04 23:10:15

24

你可以試試這個:

obj.__dict__.update(my_data_dict) 
+6

這將不適用於繼承屬性。 – 2012-05-21 12:31:56

+1

它不適用於繼承屬性的含義是什麼? – 2014-04-26 10:59:16

+0

另外,你是否試圖更新一個ForeignKey,使用__dict__,相關的值名稱是'field_name_id'而不是'field_name',你需要小心。 – levi 2015-10-01 07:00:36

3

好像你想要做這樣一個自然的事,但像你我還沒有發現它在文檔無論是。文檔確實說你應該在模型上分類save()。這就是我所做的。

def save(self, **kwargs): 
    mfields = iter(self._meta.fields) 
    mods = [(f.attname, kwargs[f.attname]) for f in mfields if f.attname in kwargs] 
    for fname, fval in mods: setattr(self, fname, fval) 
    super(MyModel, self).save() 
+1

考慮爲模型添加一個新的方法「dict_save」(所以2模型保存方法 - 正常和字典)與上面的身體上次下次我需要這個裝飾的裝飾器。我查了一下我用來做這件事的代碼,除了我在保存之外這麼做以外,其他都是一樣的。有一個方法update_model_obj_from_dict(model_object,update_dict)與上面幾乎相同的主體,並且預計我會選擇何時調用save()。我有點喜歡有選擇。所以也許在模型上的一個方法稱爲「set_from_dict」,除了最後一行以外的所有內容,以及稍後使用save。 – Purrell 2012-03-23 20:43:52

2

我得到主鍵的名字,用它來與Queryset.filter()和更新與Queryset.update()進行過濾。

fooinstance = ...  
# Find primary key and make a dict for filter 
pk_name foomodel._meta.pk.name 
filtr = {pk_name: getattr(fooinstance, pk_name)} 
# Create a dict attribute to update 
updat = {'name': 'foo', 'lastname': 'bar'} 
# Apply 
foomodel.objects.filter(**filtr).update(**updat) 

這使我可以更新任何主鍵的實例。

1

更新使用update()

Discussion.objects.filter(slug=d.slug) 
    .update(title=form_data['title'], 
      category=get_object_or_404(Category, pk=form_data['category']), 
      description=form_data['description'], closed=True) 
+0

歡迎來到SO。發佈答案時,請包含您的代碼的說明,並記住格式化文本。 – Tony 2017-03-13 09:36:21

相關問題