動態設定django的model field的預設值操作步驟
問題背景
django的model field需要動態設定預設值,具體案例如下:
原始程式碼如下,model是Application,其中欄位ignore_fort的預設值設定為False
class Application(TimestampedModel): name = models.CharField(max_length=255,null=True) ignore_fort = models.BooleanField(default=False)
然而現在有這樣一個需求:default需要根據某個變數ENV進行動態設定,如果ENV是UAT或者FAT(不區分大小寫,具體分支,比如uaT01也可以),則default設定為True,否則設定為False
首先想到的是如下程式碼:
class Application(TimestampedModel): name = models.CharField(max_length=255,null=True) ignore_fort = models.BooleanField(default= 'UAT'in ENV.upper() or 'FAT' in ENV.upper())
通過python manage.py shell_plus啟動shell除錯,發現如果ENV本來設定的是什麼值,邏輯正確,如果在shell中修改ENV的值,則新建的model的ignore_fort值並不是根據當前ENV值進行設定,而是保持原來的值,達不到需求。例如,ENV值本來設定為uat,那麼新建app = Application(),print app.ignore_fort結果是True,修改ENV ENV = 'hhh',app1 = Application(); print app1.ignore_fort結果還是True,而我們需要的是False。
分析
官方描述如下:
The default value for the field. This can be a value or a callable object. If callable it will be called every time a new object is created.
如果想要在建立物件時動態修改default的值,需要用callable object,可以理解為函式呼叫?
上述程式碼的default值並不是callable object,所以並不是在object建立時同臺更新。
解決方法
參考 正解如下,用一個函式呼叫實現callable object,進而實現動態跟新default
def get_default_ignore_fort(): cur_env =ENV.upper() return any(i in cur_env for i in ('UAT','FAT')) class Application(TimestampedModel): name = models.CharField(max_length=255,null=True) ignore_fort = models.BooleanField(default=get_default_ignore_fort)
補充知識:Django ModelChoiceField:過濾查詢集並將預設值設定為物件
我有一個Django Form類定義喜歡這個在Models:
class AccountDetailsForm(forms.Form): ... adminuser = forms.ModelChoiceField(queryset=User.objects.all())
這工作正常,但它有一些限制,我似乎不能解決:
(1)我想在查詢集上使用一個過濾器,基於傳遞給表單的變數accountid,如下所示:
User.objects.filter(account=accountid)
這不能在模型中工作,因為accountid不能作為一個變數傳遞,當然。
因此,查詢集必須以某種方式在檢視中定義,但就我可以看到它是一個必需的欄位在Form類。
(2)我想預設選擇AccountDetailsForm資料庫中的一個物件,我可以在檢視中選擇這樣:
User.objects.filter(account=accountid).filter(primary_user=1)
我試過指定adminuser作為預設值在窗體中,(它與其他標準表單欄位,如CharField工作):
adminuser = User.objects.filter(account=accountid).filter(primary_user=1) ... form = AccountDetailsForm({'adminuser': adminuser}) return render_to_response('accounts/edit/accountdetails.html',{'form': form,'account':account})
但沒有運氣。
我應該使用除ModelChoiceField之外的其他方式給我這裡需要的靈活性嗎?
謝謝。
覆蓋init方法並接受新的關鍵字引數
class AccountDetailsForm(forms.Form): ... adminuser = forms.ModelChoiceField(queryset=User.objects.all()) def __init__(self,*args,**kwargs): accountid = kwargs.pop('accountid',None) super(AccountDetailsForm,self).__init__(*args,**kwargs) if accountid: self.fields['adminuser'].queryset = User.objects.filter(account=accountid) form = AccountDetailsForm(accountid=3)
您可以隨時在檢視中手動設定選擇。
form = AccountDetailsForm()
form.fields['adminuser'].queryset = User.objects.filter(account=accountid)
警告:您不是通過將字典傳遞到您的示例中的表單來設定預設值。
你實際上建立了一個繫結表,可能觸發驗證和所有的爵士。
要設定預設值,use the initials argument.
form = AccountDetailsForm(initial={'adminuser':'3'})
翻譯自:這裡
以上這篇動態設定django的model field的預設值操作步驟就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。