一、无法动态更新数据的实例

1. 如下,数据库中创建了班级表和教师表,两张表的对应关系为“多对多”

 from django.db import models

 class Classes(models.Model):
title = models.CharField(max_length=) class Teacher(models.Model):
name = models.CharField(max_length=)
t2c = models.ManyToManyField(Classes) models.py

2. views的功能有查看、添加、编辑班级或教师表

 from django.shortcuts import render, redirect
from school import models
from django.forms import Form, fields, widgets #班级表单验证规则
class ClsForm(Form):
title = fields.RegexField('老男孩', error_messages={'invalid': '请以 老男孩 开头'}) #教师表单验证规则
class TchForm(Form):
name = fields.CharField(max_length=, min_length=, widget=widgets.TextInput(attrs={'class': 'form-control'}))
t2c = fields.MultipleChoiceField(
choices=models.Classes.objects.values_list('id', 'title'),
widget=widgets.SelectMultiple(attrs={'class': 'form-control'})
) #查看班级列表
def classes(request):
cls_list = models.Classes.objects.all()
return render(request, 'classes.html', {'cls_list': cls_list}) #查看教师列表
def teachers(request):
tch_list = models.Teacher.objects.all()
return render(request, 'teachers.html', {'tch_list': tch_list}) #添加班级
def add_cls(request):
if request.method == 'GET':
obj = ClsForm()
return render(request, 'add_classes.html', {'obj': obj})
else:
obj = ClsForm(request.POST)
if obj.is_valid():
models.Classes.objects.create(**obj.cleaned_data)
return redirect('/school/classes/')
return render(request, 'add_classes.html', {'obj': obj}) #添加教师
def add_tch(request):
if request.method == 'GET':
obj = TchForm()
return render(request, 'add_teacher.html', {'obj': obj})
else:
obj = TchForm(request.POST)
if obj.is_valid():
tc = obj.cleaned_data.pop('t2c') # 获取教师任课班级id
tch_obj = models.Teacher.objects.create(name=obj.cleaned_data['name']) # 添加新教师姓名
tch_obj.t2c.add(*tc) # 添加新教师任课班级
return redirect('/school/teachers/')
return render(request, 'add_teacher.html', {'obj': obj}) #编辑班级
def edit_cls(request, nid):
if request.method == 'GET':
cls = models.Classes.objects.filter(id=nid).first()
obj = ClsForm(initial={'title': cls.title})
return render(request, 'edit_classes.html', {'nid': nid, 'obj': obj})
else:
obj = ClsForm(request.POST)
if obj.is_valid():
models.Classes.objects.filter(id=nid).update(**obj.cleaned_data)
return redirect('/school/classes/')
return render(request, 'edit_classes.html', {'nid': nid, 'obj': obj}) #编辑教师
def edit_tch(request, nid):
if request.method == 'GET':
tch = models.Teacher.objects.filter(id=nid).first()
v = tch.t2c.values_list('id') # 获取该教师任课班级的id
cls_ids = list(zip(*v))[] if list(zip(*v)) else [] # 格式化为列表类型
obj = TchForm(initial={'name': tch.name, 't2c': cls_ids})
return render(request, 'edit_teacher.html', {'nid': nid, 'obj': obj})
else:
obj = TchForm(request.POST)
if obj.is_valid():
tc = obj.cleaned_data.pop('t2c') # 获取修改后的任课班级id
# models.Teacher.objects.filter(id=nid).update(name=obj.cleaned_data['name']) # 更新教师姓名方法1
tch_obj = models.Teacher.objects.filter(id=nid).first()
tch_obj.name = obj.cleaned_data['name'] # 更新教师姓名方法2
tch_obj.save()
tch_obj.t2c.set(tc)
return redirect('/school/teachers/')
return render(request, 'edit_teacher.html', {'nid': nid, 'obj': obj}) views.py

3. html文件

classe:

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>班级列表</title>
<link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css">
</head>
<body>
<div style="width: 700px; margin: 30px auto">
<a class="btn btn-default" href="/school/add_cls/" style="margin-bottom: 10px">添加班级</a>
<table class="table table-hover" border="" cellspacing="">
<thead>
<tr>
<th>ID</th>
<th>班级</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for item in cls_list %}
<tr>
<td>{{ item.id }}</td>
<td>{{ item.title }}</td>
<td><a href="/school/edit_cls/{{ item.id }}">编辑</a></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</body>
</html> classes.html
 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>添加班级</title>
</head>
<body>
<h1>添加班级</h1>
<form action="/school/add_cls/" method="post">
{% csrf_token %}
<p>
{{ obj.title }} {{ obj.errors.title. }}
</p>
<input type="submit" value="提交">
</form>
</body>
</html> add_classes.html
 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>编辑班级</title>
</head>
<body>
<h1>编辑班级</h1>
<form action="/school/edit_cls/{{ nid }}" method="post">
{% csrf_token %}
<p>
{{ obj.title }} {{ obj.errors.title. }}
</p>
<input type="submit" value="提交">
</form>
</body>
</html> edit_classes.html

teachers:

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>教师列表</title>
<link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css">
</head>
<body>
<div style="width: 700px; margin: 30px auto">
<a class="btn btn-default" href="/school/add_tch/" style="margin-bottom: 10px">添加教师</a>
<table class="table table-hover" border="" cellspacing="">
<thead>
<tr>
<th>ID</th>
<th>姓名</th>
<th>任教班级</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for item in tch_list %}
<tr>
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
<td>
{% for row in item.t2c.all %}
<span style="border: solid gray 1px">{{ row.title }}</span>
{% endfor %}
</td>
<td><a href="/school/edit_tch/{{ item.id }}">编辑</a></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</body>
</html> teachers.html
 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>添加教师</title>
<link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css">
</head>
<body>
<div style="width: 500px; margin: 20px auto">
<h3 style="width: 100px; margin: 10px auto">添加教师</h3>
<form class="form-horizontal" action="/school/add_tch/" method="post">
{% csrf_token %}
<div class="form-group">
<label class="col-sm-2 control-label">姓名</label>
<div class="col-sm-10">
{{ obj.name }} {{ obj.errors.name. }}
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">班级</label>
<div class="col-sm-10">
{{ obj.t2c }} {{ obj.errors.t2c. }}
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<input type="submit" class="btn btn-default" value="提交"></input>
</div>
</div>
</form>
</div>
</body>
</html> add_teacher.html
 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>编辑教师</title>
<link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css">
</head>
<body>
<div style="width: 500px; margin: 20px auto">
<h3 style="width: 100px; margin: 10px auto">编辑教师</h3>
<form class="form-horizontal" action="/school/edit_tch/{{ nid }}" method="post">
{% csrf_token %}
<div class="form-group">
<label class="col-sm-2 control-label">姓名</label>
<div class="col-sm-10">
{{ obj.name }} {{ obj.errors.name. }}
</div>
</div> <div class="form-group">
<label class="col-sm-2 control-label">班级</label>
<div class="col-sm-10">
{{ obj.t2c }} {{ obj.errors.t2c. }}
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<input type="submit" class="btn btn-default" value="提交"></input>
</div>
</div>
</form>
</div>
</body>
</html> edit_teacher.html

4. 数据不能同步

在班级表中新增一条记录

在教师表中新添加一名教师,发现无法获取上一步新增记录

5. 原因分析

在添加教师时,请求方式为GET,html标签由Form组件自动生成,其中的数据也是由Form组件提供

而TchForm作为一个类,在project运行起来后,其中的name和t2c字段都是类的变量,其只执行一次,就将数据保存在内存中,无论之后生成多少个TchForm对象,其中的字段的值都不变。

所以会出现教师表中的班级多选列表无法动态更新。

二、解决上述bug的方法

每次更新数据库后重启project,让Form类重新初始化,能够让数据更新,但这显然是不切实际的。

知道了bug的根源,我们可以尝试让每次生成TchForm对象时就更新数据:

方法一

1. 利用 __init__将数据库操作放入对象变量中

 #教师表单验证规则
class TchForm(Form):
name = fields.CharField(max_length=, min_length=, widget=widgets.TextInput(attrs={'class': 'form-control'}))
t2c = fields.MultipleChoiceField(
# choices=models.Classes.objects.values_list('id', 'title'),
widget=widgets.SelectMultiple(attrs={'class': 'form-control'})
) def __init__(self, *args, **kwargs): # 自定义__init__
super(TchForm, self).__init__(*args, **kwargs) # 调用父类的__init__
self.fields['t2c'].choices = models.Classes.objects.values_list('id', 'title') # 为字段t2c的choices赋值 修改TchForm类

2. 验证

在班级表中新增一条记录

再在教师表中添加

方法二

1. 利用django.forms.models模块中的queryset连接数据库

 #教师表单验证规则
from django.forms import models as form_models # 导入django.forms.models
class TchForm(Form):
name = fields.CharField(max_length=, min_length=, widget=widgets.TextInput(attrs={'class': 'form-control'}))
#重新定义字段
t2c = form_models.ModelMultipleChoiceField(
# choices=models.Classes.objects.values_list('id', 'title'),
queryset=models.Classes.objects.all(), # 利用queryset连接数据库,只能连接object类型
widget=widgets.SelectMultiple(attrs={'class': 'form-control'})
) 修改TchForm类

2. 验证

由于TchForm类中,queryset只能连接object类型,所以,需要设置models.py中的Classes类的返回值。

 class Classes(models.Model):
title = models.CharField(max_length=) def __str__(self):
return self.title

在班级表中新增一条记录

再在教师表中添加

原文:http://www.cnblogs.com/OldJack/p/7121510.html

【Django】Django—Form两种解决表单数据无法动态刷新的方法的更多相关文章

  1. Django—Form两种解决表单数据无法动态刷新的方法

    一.无法动态更新数据的实例 1. 如下,数据库中创建了班级表和教师表,两张表的对应关系为“多对多” from django.db import models class Classes(models. ...

  2. 两种解决IE6不支持固定定位的方法

    有两种让IE6支持position:fixed1.用CSS执行表达式 *{margin:0;padding:0;} * html,* html body{ background-image:url(a ...

  3. react当中两种获取表单数据的方法

    方法一: 获取dom当中的数据 需要操作的dom上面有  ref="test", 当需要获取的时候  this.refs.test.value  就可以获取当前输入框的value值 ...

  4. Django学习——ajax发送其他请求、上传文件(ajax和form两种方式)、ajax上传json格式、 Django内置序列化(了解)、分页器的使用

    1 ajax发送其他请求 1 写在form表单 submit和button会触发提交 <form action=""> </form> 注释 2 使用inp ...

  5. 史上最全的CSS hack方式一览 jQuery 图片轮播的代码分离 JQuery中的动画 C#中Trim()、TrimStart()、TrimEnd()的用法 marquee 标签的使用详情 js鼠标事件 js添加遮罩层 页面上通过地址栏传值时出现乱码的两种解决方法 ref和out的区别在c#中 总结

    史上最全的CSS hack方式一览 2013年09月28日 15:57:08 阅读数:175473 做前端多年,虽然不是经常需要hack,但是我们经常会遇到各浏览器表现不一致的情况.基于此,某些情况我 ...

  6. 64位win10系统无法安装.Net framework3.5的两种解决方法

    参考网站: https://blog.csdn.net/zang141588761/article/details/52177290 在Windows10中,当我们安装某些软件的时候会提示“你的电脑上 ...

  7. 64位win10系统无法安装.Net framework3.5的两种解决方法【转】

    近日有网友反映在windows10_64位系统电脑上安装Net framework3.5,操作时总失败,怎么办呢?小编下面就介绍win10 64位系统无法安装Net framework3.5的两种解决 ...

  8. 电脑出现kernelbase.dll错误的两种解决方法

    KernelBase.dll是Windows操作系统的重要文件,它为各种应用程序提供服务.如果电脑提示kernelbase.dll错误,这该怎么处理?大家可以用电脑自带的防火墙或者是第三方软件来进行故 ...

  9. ListView+CheckBox两种解决方式及原因分析

    近期在用ListView+CheckBox搞一个item选中的项目,我将CheckBox的focus设置为false,另我大喜的是,CheckBox居然能够选中(窃喜中),这么简单就搞定了,由于数据量 ...

随机推荐

  1. 20155231 2016-2017-2 《Java程序设计》第4周学习总结

    20155231 2016-2017-2 <Java程序设计>第4周学习总结 教材学习内容总结 学习目标 理解封装.继承.多态的关系 理解抽象类与接口的区别 掌握S.O.L.I.D原则 了 ...

  2. 【待解决】关于CLASSPATH的显示问题

    CLASSPATH? 环境变量? 环境变量CLASSPATH是操作系统JVM的搜索路径,它可以让JVM依据这些路径找到可执行文件.class文件,就相当于环境变量PATH对操作系统windows的作用 ...

  3. 20155320 2016-2017-2 《Java程序设计》第的四周学习总结

    20155320 2016-2017-2 <Java程序设计>第的四周学习总结 教材学习内容总结 继承与多态 继承就是子承父类,避免重复定义共同行为,会使用extends关键词,表示会扩展 ...

  4. 20155330 2016-2017-2 《Java程序设计》第二周学习总结

    20155330 2016-2017-2 <Java程序设计>第二周学习总结 教材学习内容总结 学习目标 了解Java编程风格 认识Java的类型与变量 掌握Java流程控制的方法(分支. ...

  5. 20155333 2016-2017-2 《Java程序设计》第一周学习总结

    <java程序设计>第一周学习总结 学习目标 •了解java基础知识 •了解JVM.JRE与JDK,并下载.安装.测试JDK •了解PATH.CLASSPATH.SOURCEPATH的作用 ...

  6. css3新增的content 的用法:

    <-----------------------------------------------文字加在内容后面----------------------------------------- ...

  7. 同步备份工具之 rsync

    1.常用同步方法 SCP. NFS. SFTP. http. samba. rsync. drbd(基于文件系统同步,效率高) 2.rsync 介绍 rsync,英文全称是 remote synchr ...

  8. Oracle用户和模式,表空间

    oracle 用户与表空间关系 oracle用户与表空间关系用户=商家表=商品表空间=仓库1. 1个商家能有很多商品,1个商品只能属于一个商家2. 1个商品可以放到仓库A,也可以放到仓库B,但不能同时 ...

  9. VBA_常用VBA代码

    '批量替换字符 Sub Test() Dim i As Integer ).Value = "已激活" Then Cells(i, ).Value = "Active&q ...

  10. SteamVR Unity Plugin - v2.0.1中的InteractionSystem

    最近写VR项目的时候用到了SteamVR Unity Plugin - v2.0.1插件,感觉比之前用到的SteamVR plugin for Unity - v1.2.2版本改进了很多,就算不用VR ...