先說明一下問題的由來(lái):
Django的模型中經(jīng)常會(huì)用ForeignKey來(lái)關(guān)聯(lián)其他表格數(shù)據(jù)
class MeasureTask(models.Model): taskname = models.CharField(max_length=LEN_FULLNAME, verbose_name="任務(wù)名稱") road = models.ForeignKey(Road, on_delete=models.CASCADE, verbose_name="設(shè)計(jì)路段") # 路面層,附加一個(gè)參數(shù) ,指定這個(gè)層的厚度,相對(duì)于底層的厚度 # road_level = models.ForeignKey(RoadLevel, on_delete=models.CASCADE, verbose_name="路面層") level_thick = models.IntegerField(default=0, verbose_name="層厚(mm)") # ...
使用Django的ModelForm轉(zhuǎn)化為表單代碼如下:
class MeasureTaskNewForm(forms.ModelForm): class Meta: model = MeasureTask fields = ('taskname', 'staff', 'start_mileage', 'end_mileage', 'road', 'level_thick', 'step', 'equip', 'comment')
如果不做進(jìn)一步處理,在網(wǎng)頁(yè)中使用這個(gè)From時(shí),關(guān)聯(lián)字段會(huì)自動(dòng)轉(zhuǎn)化為一個(gè)select控件,里面包含了所有選項(xiàng),如下圖:
實(shí)際應(yīng)用時(shí),需要對(duì)關(guān)聯(lián)的字段做一些選擇過濾。期望的結(jié)果如下:
在From類中設(shè)置一個(gè)初始化函數(shù):
class MeasureTaskNewForm(forms.ModelForm): class Meta: model = MeasureTask fields = ('taskname', 'staff', 'start_mileage', 'end_mileage', 'road', 'level_thick', 'step', 'equip', 'comment') # 對(duì)參數(shù)作初始化設(shè)置,導(dǎo)致返回之后的Form驗(yàn)證失敗 def __init__(self, road_choices=None, *args, **kwargs): super(MeasureTaskNewForm, self).__init__(*args, **kwargs) if road_choices: self.fields['road'].choices = road_choices
應(yīng)用這個(gè)類的方式如下,注意傳入?yún)?shù)的數(shù)據(jù)類型,
# 對(duì)關(guān)聯(lián)數(shù)據(jù)過濾 roads = Road.objects.filter(project=p_item) # 生成值,分別對(duì)應(yīng)于 html 中 select->option 設(shè)置 choices = roads.values_list('id', 'name') dataform = MeasureTaskNewForm(road_choices=choices) # dataform = MeasureTaskNewFormShadow() return render(request, "mdata/html/measure_task_add.html", locals())
生成的html代碼:
select name="road" id="id_road" class="form-control"> option value="1">北四環(huán)主線/option> option value="5">匝道A/option> /select>
到這里生成的表單頁(yè)面沒有問題了,但是表單提交返回時(shí)如果還是用這個(gè)From來(lái)接收Request數(shù)據(jù),則會(huì)出現(xiàn)數(shù)據(jù)校驗(yàn)失敗的問題
if request.method == "POST": dataform = MeasureTaskNewForm(request.POST) # 這里將出現(xiàn)校驗(yàn)失敗的問題 if dataform.is_valid(): dataform.save() return redirect('mdata:measure_task', pid=p_item.id)
為了解決這個(gè)問題,另外做了一個(gè)沒有初始化函數(shù)的表單類來(lái)接收數(shù)據(jù).
# 影子表單模型 class MeasureTaskNewFormShadow(forms.ModelForm): class Meta: model = MeasureTask fields = ('taskname', 'staff', 'start_mileage', 'end_mileage', 'road', 'level_thick', 'step', 'equip', 'comment')
if request.method == "POST": dataform = MeasureTaskNewFormShadow(request.POST) if dataform.is_valid(): dataform.save() return redirect('mdata:measure_task', pid=p_item.id)
感覺這里應(yīng)該有更好的方法,嘗試對(duì)Form的初始化函數(shù)做了一些修改,但是沒有成功。
https://qastack.cn/programming/813418/django-set-field-value-after-a-form-is-initialized
http://hk.uwenku.com/question/p-vdjpsmjn-bes.html
https://www.itranslater.com/qa/details/2325790729974580224
到此這篇關(guān)于Django表單外鍵選項(xiàng)初始化的文章就介紹到這了,更多相關(guān)Django表單初始化內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
標(biāo)簽:景德鎮(zhèn) 欽州 黃山 宿遷 三沙 喀什 濟(jì)南 臺(tái)灣
巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《Django表單外鍵選項(xiàng)初始化的問題及解決方法》,本文關(guān)鍵詞 Django,表單,外鍵,選項(xiàng),初始化,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。