動(dòng)態(tài)設(shè)置django的model field的默認(rèn)值操作步驟
問(wèn)題背景
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ū)分大小寫(xiě),具體分支,比如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())
通過(guò)python manage.py shell_plus啟動(dòng)shell調(diào)試,發(fā)現(xiàn)如果ENV本來(lái)設(shè)置的是什么值,邏輯正確,如果在shell中修改ENV的值,則新建的model的ignore_fort值并不是根據(jù)當(dāng)前ENV值進(jìn)行設(shè)置,而是保持原來(lái)的值,達(dá)不到需求。例如,ENV值本來(lái)設(shè)置為uat,那么新建app = Application(),print app.ignore_fort結(jié)果是True,修改ENV ENV = 'hhh',app1 = Application(); print app1.ignore_fort結(jié)果還是True,而我們需要的是False。
分析
官方描述如下:
如果想要在創(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:過(guò)濾查詢集并將默認(rèn)值設(shè)置為對(duì)象
我有一個(gè)Django Form類定義喜歡這個(gè)在Models:
class AccountDetailsForm(forms.Form): ... adminuser = forms.ModelChoiceField(queryset=User.objects.all())
這工作正常,但它有一些限制,我似乎不能解決:
(1)我想在查詢集上使用一個(gè)過(guò)濾器,基于傳遞給表單的變量accountid,如下所示:
User.objects.filter(account=accountid)
這不能在模型中工作,因?yàn)閍ccountid不能作為一個(gè)變量傳遞,當(dāng)然。
因此,查詢集必須以某種方式在視圖中定義,但就我可以看到它是一個(gè)必需的字段在Form類。
(2)我想默認(rèn)選擇AccountDetailsForm數(shù)據(jù)庫(kù)中的一個(gè)對(duì)象,我可以在視圖中選擇這樣:
User.objects.filter(account=accountid).filter(primary_user=1)
我試過(guò)指定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})
但沒(méi)有運(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)
警告:您不是通過(guò)將字典傳遞到您的示例中的表單來(lái)設(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è)參考,也希望大家多多支持腳本之家。
相關(guān)文章
使用pytorch搭建AlexNet操作(微調(diào)預(yù)訓(xùn)練模型及手動(dòng)搭建)
今天小編就為大家分享一篇使用pytorch搭建AlexNet操作(微調(diào)預(yù)訓(xùn)練模型及手動(dòng)搭建),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-01-01Python實(shí)現(xiàn)柵欄密碼的加密解密方法詳解
這篇文章主要介紹了Python實(shí)現(xiàn)柵欄密碼的加密解密方法,所謂柵欄密碼,就是把要加密的明文分成N個(gè)一組,然后把每組的第1個(gè)字連起來(lái),形成一段無(wú)規(guī)律的話。不過(guò)柵欄密碼本身有一個(gè)潛規(guī)則,就是組成柵欄的字母一般不會(huì)太多2023-01-01Win8.1下安裝Python3.6提示0x80240017錯(cuò)誤的解決方法
這篇文章主要為大家詳細(xì)介紹了Win8.1下安裝Python3.6提示0x80240017錯(cuò)誤的解決方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-07-07windows系統(tǒng)IIS部署Django項(xiàng)目的實(shí)踐
采用IIS服務(wù)器部署相比django提供的開(kāi)發(fā)者服務(wù)器具有更好的并發(fā)訪問(wèn)能力,性能更加穩(wěn)定,本文主要介紹了windows系統(tǒng)IIS部署Django項(xiàng)目的實(shí)踐,具有一定的參考價(jià)值,感興趣的可以了解一下2022-03-03python使用pgzero進(jìn)行游戲開(kāi)發(fā)
今天要和大家分享的pgzero(pygame zero)是在pygame基礎(chǔ)上做了進(jìn)一步的封裝,使得設(shè)計(jì)一款游戲十分的方便,特別適合少兒編程領(lǐng)域的教學(xué), 與scratch相得益彰。2021-06-06python GUI庫(kù)圖形界面開(kāi)發(fā)之PyQt5信號(hào)與槽基礎(chǔ)使用方法與實(shí)例
這篇文章主要介紹了python GUI庫(kù)圖形界面開(kāi)發(fā)之PyQt5信號(hào)與槽基礎(chǔ)使用方法與實(shí)例,需要的朋友可以參考下2020-03-03用Python把csv文件批量修改編碼為UTF-8格式并轉(zhuǎn)為Excel格式的方法
有時(shí)候用excel打開(kāi)一個(gè)csv文件,中文全部顯示亂碼,然后手動(dòng)用notepad++打開(kāi),修改編碼為utf-8并保存后,再用excel打開(kāi)顯示正常,本文將給大家介紹一下用Python把csv文件批量修改編碼為UTF-8格式并轉(zhuǎn)為Excel格式的方法,需要的朋友可以參考下2023-09-09