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

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

(0)

相关推荐

  • django初始化数据库的实例

    最近项目需要,需要在表创建好之后,初始化一些数据.Django初始化数据的方法有很多,但都需要额外的手动操作,不智能. 看网上有一种方法用post_syncdb信号来初始化数据库,但是我用的Django版本是1.8, 使用python manage.py migrate来同步数据库,不使用Python manage.py syncdb来同步数据库,就想看看能否使用post_migrate信号来初始化数据库.研究了Django的signal,试了一下,果然可以. 在你的APP目录下,创建一个文件m

  • 在django-xadmin中APScheduler的启动初始化实例

    环境: python3.5.x + django1.9.x + xadmin-for-python3 APScheduler做为一个轻量级和使用量很多的后台任务计划(scheduler)包,可以方便的随系统启动/关闭而启动/关闭,如果整合到django中,启动APScheduler的代码该写在哪里好呢, 以下几个方式供参考: 1. (推荐)自定义Middleware,非常类似Java中的Filter,缺点是要有URL访问才会触发启动,如果系统还没有启动完就访问了URL会触发__init__多次调

  • 在Django同1个页面中的多表单处理详解

    快速上手Django实现项目 近期公司在做1个海淘的项目,APP为pylot.由于时间比较赶,加上隔壁那哥们不在,只能自己挑大梁了.结果,当项目做出来之后,被领导狠狠的批了一顿,说怎么用django写,你能解决Django的内存问题吗,你能解决并发的问题吗?Django那么重. 然后我只好回答说,正是因为它重,所以人家拿来写大型项目.虽然这里不是为了上面这2个问题的,而是来说下如何快速开发原型的问题. 对于Django这样基于模型的Web框架,实话说真的解决了很多繁琐的工作.由于它1个模型对应1

  • django表单实现下拉框的示例讲解

    方法一: queue = forms.ModelChoiceField(label=u'队列',queryset=Queue.objects.all()) 方法二: class ServerForm(forms.Form): queue = forms.ChoiceField(label=u'队列') def __init__(self,*args,**kwargs): super(ServerForm,self).__init__(*args,**kwargs) self.fields['qu

  • Python的Django框架中forms表单类的使用方法详解

    Form表单的功能 自动生成HTML表单元素 检查表单数据的合法性 如果验证错误,重新显示表单(数据不会重置) 数据类型转换(字符类型的数据转换成相应的Python类型) Form相关的对象包括 Widget:用来渲染成HTML元素的工具,如:forms.Textarea对应HTML中的<textarea>标签 Field:Form对象中的一个字段,如:EmailField表示email字段,如果这个字段不是有效的email格式,就会产生错误. Form:一系列Field对象的集合,负责验证和

  • 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="设计路段")

  • 阻止表单提交按钮多次提交的完美解决方法

    如果表单是通过onsubmit进行Ajax提交,注意将表单提交按钮input type属性设为button,尽量不要设置为submit类型. 另外,在提交事件发出后,最好将提交按钮设置为disabled,防止由于网络延时问题,让用户有机会进行多次点击重复提交. onclick事件里面执行 $(this).attr('disabled','disabled'); 在点击一次后立马将按钮设置为不可使用. 或者向如下方法另行定义一个jQuery函数来进行控制: $("form").submi

  • 详谈表单重复提交的三种情况及解决方法

    第一种情况:提交完表单以后,不做其他操作,直接刷新页面,表单会提交多次. - 在servlet中写一句输出,用来判断是否提交多次 System.out.println("已经插入"); request.getRequestDispatcher("/login_success.jsp").forward(request, response); - 这样的话,刷新多少次,就会在控制器显示多少个"已经插入". - 根本原因:Servlet处理完请求以后

  • 点击表单提交时出现jQuery没有权限的解决方法

    今天遇到个问题 我点击表单提交的时候会出现 jQuery 没有权限 : 百度了一堆都是说 jquery跨域之类的原因,比对项目,发现没有这样的原因:但是还是受到其中的启发,使用json可以防止这类问题,但是他们提供的办法都比较复杂,需要改前台和后台. 试了一下jquery自带的json方式提交成功! $.post("actionName.action",{"id":值,"name":值}, function(data){ if(data==&qu

  • 表单Form的submit事件不响应的解决方法

    一.问题描述 类比一下,我用input.select()做了测试,却能响应select事件.这个原因先放一边,我们看看先怎么把眼下的问题解决了. 不响应事件的代码示例: var form = document.getElementById('form1'); form.onsubmit = function() { alert(1); }; form.submit(); [Ctrl+A 全选 注:如需引入外部Js需刷新才能执行] 实际运行,不会有alert出来. 虽然用submit方法来提交表单

  • Django Admin 实现外键过滤的方法

    说明和 Model 环境: ➜ python Python 3.6.3 |Anaconda custom (x86_64)| (default, Oct 6 2017, 12:04:38) [GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)] on darwin Type "help", "copyright", "credits" or "license" f

  • Oracle批量执行sql语句之禁用所有表的外键

    在转移数据库,进行数据导入的时候,遇到一件麻烦事,就是表间外键约束的存在,导致insert频频报错,批量执行sql语句又是顺序执行,没办法我只好手动输入. 然后输入到一半灵光一闪,为什么不先把外键约束全部禁用先呢? 于是我百度到以下资料: oracle 删除(所有)约束 禁用(所有)约束 启用(所有)约束 执行以下sql生成的语句即可 1删除所有外键约束 select 'alter table '||table_name||' drop constraint '||constraint_name

  • MySQL 关闭子表的外键约束检察方法

    准备: 定义一个教师表.一个学生表:在学生表中引用教师表ID create table teachers(teacherID int not null auto_increment primary key,teacherName varchar(8)); create table students(studentID int not null auto_increment primary key,teacherID int not null,studentName varchar(8), con

  • django admin.py 外键,反向查询的实例

    如下所示: class OrderAdmin(admin.ModelAdmin): list_display = ( '_nick_name', 'time_order', 'year', 'item', 'status', 'number', 'money', 'deduction_point', 'deduction_account', 'pay', '_open_id', 'out_trade_no', ) search_fields = [ 'user__nick_name', 'use

随机推荐