溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

動(dòng)態(tài)設(shè)置django的model field的默認(rèn)值操作步驟

發(fā)布時(shí)間:2020-08-28 14:03:12 來源:腳本之家 閱讀:603 作者:ly005 欄目:開發(fā)技術(shù)

問題背景

django的model field需要?jiǎng)討B(tài)設(shè)置默認(rèn)值,具體案例如下:

原始代碼如下,model是Application,其中字段ignore_fort的默認(rèn)值設(shè)置為False

class Application(TimestampedModel):
  name = models.CharField(max_length=255, null=True)
  ignore_fort = models.BooleanField(default=False)

然而現(xiàn)在有這樣一個(gè)需求:default需要根據(jù)某個(gè)變量ENV進(jìn)行動(dòng)態(tài)設(shè)置,如果ENV是UAT或者FAT(不區(qū)分大小寫,具體分支,比如uaT01也可以),則default設(shè)置為True,否則設(shè)置為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啟動(dòng)shell調(diào)試,發(fā)現(xiàn)如果ENV本來設(shè)置的是什么值,邏輯正確,如果在shell中修改ENV的值,則新建的model的ignore_fort值并不是根據(jù)當(dāng)前ENV值進(jìn)行設(shè)置,而是保持原來的值,達(dá)不到需求。例如,ENV值本來設(shè)置為uat,那么新建app = Application(),print app.ignore_fort結(jié)果是True,修改ENV ENV = 'hhh',app1 = Application(); print app1.ignore_fort結(jié)果還是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.

如果想要在創(chuàng)建對(duì)象時(shí)動(dòng)態(tài)修改default的值,需要用callable object,可以理解為函數(shù)調(diào)用?

上述代碼的default值并不是callable object,所以并不是在object創(chuàng)建時(shí)同臺(tái)更新。

解決方法

參考 正解如下,用一個(gè)函數(shù)調(diào)用實(shí)現(xiàn)callable object,進(jìn)而實(shí)現(xiàn)動(dòng)態(tài)跟新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)

補(bǔ)充知識(shí):Django ModelChoiceField:過濾查詢集并將默認(rèn)值設(shè)置為對(duì)象

我有一個(gè)Django Form類定義喜歡這個(gè)在Models:

class AccountDetailsForm(forms.Form):
  ...
  adminuser = forms.ModelChoiceField(queryset=User.objects.all())

這工作正常,但它有一些限制,我似乎不能解決:

(1)我想在查詢集上使用一個(gè)過濾器,基于傳遞給表單的變量accountid,如下所示:

User.objects.filter(account=accountid)

這不能在模型中工作,因?yàn)閍ccountid不能作為一個(gè)變量傳遞,當(dāng)然。

因此,查詢集必須以某種方式在視圖中定義,但就我可以看到它是一個(gè)必需的字段在Form類。

(2)我想默認(rèn)選擇AccountDetailsForm數(shù)據(jù)庫中的一個(gè)對(duì)象,我可以在視圖中選擇這樣:

User.objects.filter(account=accountid).filter(primary_user=1)

我試過指定adminuser作為默認(rèn)值在窗體中,(它與其他標(biāo)準(zhǔn)表單字段,如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})

但沒有運(yùn)氣。

我應(yīng)該使用除ModelChoiceField之外的其他方式給我這里需要的靈活性嗎?

謝謝。

覆蓋init方法并接受新的關(guān)鍵字參數(shù)

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)

您可以隨時(shí)在視圖中手動(dòng)設(shè)置選擇。

form = AccountDetailsForm()
form.fields['adminuser'].queryset = User.objects.filter(account=accountid)


警告:您不是通過將字典傳遞到您的示例中的表單來設(shè)置默認(rèn)值。

你實(shí)際上創(chuàng)建了一個(gè)綁定表,可能觸發(fā)驗(yàn)證和所有的爵士。

要設(shè)置默認(rèn)值,use the initials argument.

form = AccountDetailsForm(initial={'adminuser':'3'})

翻譯自:這里

以上這篇?jiǎng)討B(tài)設(shè)置django的model field的默認(rèn)值操作步驟就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持億速云。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI