服务器之家

服务器之家 > 正文

Django表单外键选项初始化的问题及解决方法

时间:2021-10-22 10:02     来源/作者:BH78

问题描述

先说明一下问题的由来:
Django的模型中经常会用ForeignKey来关联其他表格数据

?
1
2
3
4
5
6
7
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转化为表单代码如下:

?
1
2
3
4
5
class MeasureTaskNewForm(forms.ModelForm):
    class Meta:
        model = MeasureTask
        fields = ('taskname', 'staff', 'start_mileage', 'end_mileage',
                  'road', 'level_thick', 'step', 'equip', 'comment')

如果不做进一步处理,在网页中使用这个From时,关联字段会自动转化为一个select控件,里面包含了所有选项,如下图:

Django表单外键选项初始化的问题及解决方法

实际应用时,需要对关联的字段做一些选择过滤。期望的结果如下:

Django表单外键选项初始化的问题及解决方法

解决方式

在From类中设置一个初始化函数:

?
1
2
3
4
5
6
7
8
9
10
11
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

应用这个类的方式如下,注意传入参数的数据类型,

?
1
2
3
4
5
6
7
# 对关联数据过滤
       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代码:

?
1
2
3
4
<select name="road" id="id_road" class="form-control">
  <option value="1">北四环主线</option>
  <option value="5">匝道A</option>
</select>

到这里生成的表单页面没有问题了,但是表单提交返回时如果还是用这个From来接收Request数据,则会出现数据校验失败的问题

?
1
2
3
4
5
6
if request.method == "POST":
        dataform = MeasureTaskNewForm(request.POST)
        # 这里将出现校验失败的问题
        if dataform.is_valid():
            dataform.save()
        return redirect('mdata:measure_task', pid=p_item.id)

为了解决这个问题,另外做了一个没有初始化函数的表单类来接收数据.

?
1
2
3
4
5
6
# 影子表单模型
class MeasureTaskNewFormShadow(forms.ModelForm):
    class Meta:
        model = MeasureTask
        fields = ('taskname', 'staff', 'start_mileage', 'end_mileage',
                  'road', 'level_thick', 'step', 'equip', 'comment')
?
1
2
3
4
5
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

到此这篇关于Django表单外键选项初始化的文章就介绍到这了,更多相关Django表单初始化内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://www.cnblogs.com/wujbclzw/archive/2021/04/29/14716862.html

标签:

相关文章

热门资讯

yue是什么意思 网络流行语yue了是什么梗
yue是什么意思 网络流行语yue了是什么梗 2020-10-11
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全 2019-12-26
背刺什么意思 网络词语背刺是什么梗
背刺什么意思 网络词语背刺是什么梗 2020-05-22
2021年耽改剧名单 2021要播出的59部耽改剧列表
2021年耽改剧名单 2021要播出的59部耽改剧列表 2021-03-05
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总 2020-11-13
返回顶部