2013-03-18 74 views
7

我有一個名爲StaffSettings的Django模型,它包含我的Django應用程序中用戶的各種配置選項。每個用戶在StaffSettings表中至多有一個條目。是否有get_or_create然後更新Django中的對象的慣用方法?

假設一個設置是default_year_level,我有代碼爲我的用戶對象,如:

def set_default_year_level(u, year_level): 
    obj, _created = StaffSettings.objects.get_or_create(user=u) 
    obj.default_year_level = year_level 
    obj.save() 

我寧願函數體,以適應在一個行,因爲它似乎是一個常見的情況,但如果我把它定義爲

def set_default_year_level(u, year_level): 
    StaffSettings.objects.filter(user=u).update(default_year_level=year_level) 

如果有問題的用戶已經在StaffSettings表中的一行,工作正常,但如果它不存在,它不會產生相關行。

什麼是這種代碼的慣用/最好的方式? (例如,是否有某種filter_or_create函數?或者其他人寫修飾符/助手函數來處理這個習慣用法?)

回答

5

我沒有看到你的第一個函數有任何問題,我會寫這個用例。

但是如果你需要很多你的模型字段相同的特徵,你不想重複自己,你可以通過現場的參數:

def set_default_value(u, field, value): 
    obj, _created = StaffSettings.objects.get_or_create(user=u) 
    setattr(obj, field, value) 
    obj.save() 

我會從遠離更新()功能反正因爲該功能是指在一次更新多個對象,並不會觸發save()方法,也沒有信號,你的模型(見https://docs.djangoproject.com/en/dev/topics/db/queries/#updating-multiple-objects-at-once

+0

感謝您提及update()的缺陷。我想我曾經讀了一次但忘記了。我已經做了類似於你的建議,但做了set_default_values(u,** kwargs),所以我不必爲字段傳遞一個字符串,而是可以編寫像set_default_values(u,default_year_level = year_level) 。 – bryn 2013-03-20 09:58:24

2

由於Django的1.7,你可以使用update_or_create()

def set_default_year_level(u, year_level): 
    obj, _created = StaffSettings.objects.update_or_create(
     user=u, 
     default_year_level=year_level 
    ) 

或者,如前面的回答解釋了更通用的情況:

def set_default_values(u, **kwargs): 
    obj, _created = StaffSettings.objects.update_or_create(user=u, defaults=kwargs) 

這也實現了您的附加要求

我寧願配合到函數體一行

相關問題