百木园-与人分享,
就是让自己快乐。

Django表单外键选项初始化

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/p/14716862.html
图文来源于网络,如有侵权请联系删除。

未经允许不得转载:百木园 » Django表单外键选项初始化

相关推荐

  • 暂无文章