Django表单外键选项初始化的问题及解决方法
作者:BH78 发布时间:2022-07-09 04:28:42
标签:Django,表单,初始化
问题描述
先说明一下问题的由来:
Django的模型中经常会用ForeignKey来关联其他表格数据
class MeasureTask(models.Model):
taskname = models.CharField(max_length=LEN_FULLNAME, verbose_name="任务名称")
road = models.ForeignKey(Road, on_delete=models.CASCADE, verbose_name="设计路段")
# 路面层,附加一个参数 ,指定这个层的厚度,相对于底层的厚度
# road_level = models.ForeignKey(RoadLevel, on_delete=models.CASCADE, verbose_name="路面层")
level_thick = models.IntegerField(default=0, verbose_name="层厚(mm)")
# ...
使用Django的ModelForm转化为表单代码如下:
class MeasureTaskNewForm(forms.ModelForm):
class Meta:
model = MeasureTask
fields = ('taskname', 'staff', 'start_mileage', 'end_mileage',
'road', 'level_thick', 'step', 'equip', 'comment')
如果不做进一步处理,在网页中使用这个From时,关联字段会自动转化为一个select控件,里面包含了所有选项,如下图:
实际应用时,需要对关联的字段做一些选择过滤。期望的结果如下:
解决方式
在From类中设置一个初始化函数:
class MeasureTaskNewForm(forms.ModelForm):
class Meta:
model = MeasureTask
fields = ('taskname', 'staff', 'start_mileage', 'end_mileage',
'road', 'level_thick', 'step', 'equip', 'comment')
# 对参数作初始化设置,导致返回之后的Form验证失败
def __init__(self, road_choices=None, *args, **kwargs):
super(MeasureTaskNewForm, self).__init__(*args, **kwargs)
if road_choices:
self.fields['road'].choices = road_choices
应用这个类的方式如下,注意传入参数的数据类型,
# 对关联数据过滤
roads = Road.objects.filter(project=p_item)
# 生成值,分别对应于 html 中 select->option 设置
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">北四环主线</option>
<option value="5">匝道A</option>
</select>
到这里生成的表单页面没有问题了,但是表单提交返回时如果还是用这个From来接收Request数据,则会出现数据校验失败的问题
if request.method == "POST":
dataform = MeasureTaskNewForm(request.POST)
# 这里将出现校验失败的问题
if dataform.is_valid():
dataform.save()
return redirect('mdata:measure_task', pid=p_item.id)
为了解决这个问题,另外做了一个没有初始化函数的表单类来接收数据.
# 影子表单模型
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)
感觉这里应该有更好的方法,尝试对Form的初始化函数做了一些修改,但是没有成功。
参考资料
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
来源:https://www.cnblogs.com/wujbclzw/archive/2021/04/29/14716862.html


猜你喜欢
- 目录模板基本语法编写主页模板准备虚拟数据渲染主页模板总结在一般的 Web 程序里,访问一个地址通常会返回一个包含各类信息的 HTML 页面。
- 概述pandas中与库版本或依赖库版本相关的API主要有以下4个:pandas.__version__:查看pandas简要版本信息。pan
- Mysql my.ini 配置文件详解 #BEGIN CONFIG INFO #DESCR: 4GB RAM, 只使用InnoDB, ACI
- 学Python之前我们先来几个简单的小游戏练练手,这三个小游戏一个比一个复杂,建议新手慢慢来:1.猜拳import random  
- 上篇文章分享了windows下载mysql5.7压缩包配置安装mysql后续可以选择①在本地创建一个数据库,使用navicat工具导出远程测
- 项目意义如果你想在支付宝蚂蚁森林收集很多能量种树,为环境绿化出一份力量,又或者是想每天称霸微信运动排行榜装逼,却不想出门走路,那么该pyth
- 一般情况下:if(2 > 10){alert("不正确!");} 此比较不会是想要的结果:它相当于2 >1,
- 一 . 得到这个对象的实例Connection con ;con = DriverManager.getConnection(url,use
- 分享两个常用的代码生成工具:gormgenhandlergengormgen基于 MySQL 数据表结构进行生成 3 个文件:生成表的 st
- 多版本并发控制Multiversion Concurrency Control大部分的MySQL的存储 引擎,比如InnoDB,Falcon
- 可视化单词统计词频统计中文分词项目架构新建一个文件,输入文件的内容,查询此文件中关键字的出现的次数,关键字出现的位置,将所有的文本按照中文分
- sql 使用系统存储过程 sp_send_dbmail 发送电子邮件语法:sp_send_dbmail [ [ @profile_name
- 1)对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。2)应尽量避免在 where 子
- 安装python中文分词库jieba法1:Anaconda Prompt下输入conda install jieba法2:Terminal下
- 代码如下:from PIL import Image #图像处理模块import numpy as npa = np.asarr
- 如下所示:import cv2import osimport numpy as nproot_path = "I:/Images/
- 写这篇文章的缘由是我使用 reqeusts 库请求接口的时候, 直接使用请求参数里的 json 字段发送数据, 但是服务器无法识别我发送的数
- pip简介pip 是一个现代的,通用的 Python 包管理工具。提供了对 Python 包的查找、下载、安装、卸载的功能pip是官方推荐的
- 程序说明:本程序实现将开发程序服务器中的打包文件通过该脚本上传到正式生产环境(注:生产环境和开发环境不互通)程序基本思路:将开发环境中的程序
- 最近因为数学建模3天速成Python,然后做了一道网络的题,要画网络图。在网上找了一些,发现都是一些很基础的丑陋红点图,并且关于网络的一些算