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

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. 2017-2018-1 20155320加分项目——pwd的实现

    2017-2018-1 20155320加分项目--pwd的实现 1 学习pwd命令 2 研究pwd实现需要的系统调用(man -k; grep),写出伪代码 3 实现mypwd 4 测试mypwd ...

  2. 20155338 2016-2017-2 《Java程序设计》第10周学习总结

    20155338 2016-2017-2 <Java程序设计>第10周学习总结 教材学习内容总结 网络编程 · 网络编程就是在两个或两个以上的设备(例如计算机)之间传输数据.程序员所作的事 ...

  3. 在windows上搭建redis集群(redis-cluster)(转载)

    一 所需软件:Redis.Ruby语言运行环境.Redis的Ruby驱动redis-xxxx.gem.创建Redis集群的工具redis-trib.rb 二 安装配置redis  redis下载地址 ...

  4. Hbase单机安装及使用hbase shell进行简单操作

    一,配置环境变量 在etc/prifile中加入java环境变量及hbase环境变量: #set java environment JAVA_HOME=/usr/local/lhc/jdk1.8.0_ ...

  5. day2 RHCE

    1.配置SELINUX 在system1和system2上要求SeLinux的状态为enforcing.要求系统重启后依然生效. server [root@server0 ~]# getenforce ...

  6. 收集的PHP工具及类库

    composer     PHP的依赖管理工具 phpmig        PHP的数据库迁移工具,依赖于composer Requests for PHP    HTTP请求库,采集页面可以用到的 ...

  7. linux 命令缩写

    su super user apt advanced packaging tool ifconfig interface configuration so shared object fsp frac ...

  8. Jmeter使用JDBC链接数据库进行压力测试

    一.关于性能测试 对数据库进行压测时,我们需要关注的几个方面: 1.系统相关指标,诸如:系统CPU/内存/IO等 2.进程相关指标,诸如:mysql该数据库的对应的进程占用CPU/内存/IO等 3.数 ...

  9. vps搭建个人网盘不二之选—kodexplorer介绍,包含安装步骤

    之前给大家介绍过seafile.h5ai等网盘系统,今天给大家介绍下kodexplorer网盘系统.Kodexplorer,也叫芒果云.可道云.kodcloud,总之名字改了不少.但其本身作为一个网盘 ...

  10. A Product Recall 产品召回

    Rick: The Board of Directors has come to a decision. Our company will take an image hit, and it's go ...