分享两种方法解决Form表单数据无法动态刷新的方法
一、无法动态更新数据的实例
1. 如下,数据库中创建了班级表和教师表,两张表的对应关系为“多对多”


1 from django.db import models 2 3 4 class Classes(models.Model): 5 title = models.CharField(max_length=32) 6 7 8 class Teacher(models.Model): 9 name = models.CharField(max_length=32)10 t2c = models.ManyToManyField(Classes)
2. views的功能有查看、添加、编辑班级或教师表


1 from django.shortcuts import render, redirect 2 from school import models 3 from django.forms import Form, fields, widgets 4 5 6 #班级表单验证规则 7 class ClsForm(Form): 8 title = fields.RegexField('老男孩', error_messages={'invalid': '请以 老男孩 开头'}) 9 10 11 #教师表单验证规则12 class TchForm(Form):13 name = fields.CharField(max_length=16, min_length=2, widget=widgets.TextInput(attrs={'class': 'form-control'}))14 t2c = fields.MultipleChoiceField(15 choices=models.Classes.objects.values_list('id', 'title'),16 widget=widgets.SelectMultiple(attrs={'class': 'form-control'})17 )18 19 20 #查看班级列表21 def classes(request):22 cls_list = models.Classes.objects.all()23 return render(request, 'classes.html', {'cls_list': cls_list})24 25 26 #查看教师列表27 def teachers(request):28 tch_list = models.Teacher.objects.all()29 return render(request, 'teachers.html', {'tch_list': tch_list})30 31 32 #添加班级33 def add_cls(request):34 if request.method == 'GET':35 obj = ClsForm()36 return render(request, 'add_classes.html', {'obj': obj})37 else:38 obj = ClsForm(request.POST)39 if obj.is_valid():40 models.Classes.objects.create(**obj.cleaned_data)41 return redirect('/school/classes/')42 return render(request, 'add_classes.html', {'obj': obj})43 44 45 #添加教师46 def add_tch(request):47 if request.method == 'GET':48 obj = TchForm()49 return render(request, 'add_teacher.html', {'obj': obj})50 else:51 obj = TchForm(request.POST)52 if obj.is_valid():53 tc = obj.cleaned_data.pop('t2c') # 获取教师任课班级id54 tch_obj = models.Teacher.objects.create(name=obj.cleaned_data['name']) # 添加新教师姓名55 tch_obj.t2c.add(*tc) # 添加新教师任课班级56 return redirect('/school/teachers/')57 return render(request, 'add_teacher.html', {'obj': obj})58 59 60 #编辑班级61 def edit_cls(request, nid):62 if request.method == 'GET':63 cls = models.Classes.objects.filter(id=nid).first()64 obj = ClsForm(initial={'title': cls.title})65 return render(request, 'edit_classes.html', {'nid': nid, 'obj': obj})66 else:67 obj = ClsForm(request.POST)68 if obj.is_valid():69 models.Classes.objects.filter(id=nid).update(**obj.cleaned_data)70 return redirect('/school/classes/')71 return render(request, 'edit_classes.html', {'nid': nid, 'obj': obj})72 73 74 #编辑教师75 def edit_tch(request, nid):76 if request.method == 'GET':77 tch = models.Teacher.objects.filter(id=nid).first()78 v = tch.t2c.values_list('id') # 获取该教师任课班级的id79 cls_ids = list(zip(*v))[0] if list(zip(*v)) else [] # 格式化为列表类型80 obj = TchForm(initial={'name': tch.name, 't2c': cls_ids})81 return render(request, 'edit_teacher.html', {'nid': nid, 'obj': obj})82 else:83 obj = TchForm(request.POST)84 if obj.is_valid():85 tc = obj.cleaned_data.pop('t2c') # 获取修改后的任课班级id86 # models.Teacher.objects.filter(id=nid).update(name=obj.cleaned_data['name']) # 更新教师姓名方法187 tch_obj = models.Teacher.objects.filter(id=nid).first()88 tch_obj.name = obj.cleaned_data['name'] # 更新教师姓名方法289 tch_obj.save()90 tch_obj.t2c.set(tc)91 return redirect('/school/teachers/')92 return render(request, 'edit_teacher.html', {'nid': nid, 'obj': obj})
3. html文件
classe:


1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>班级列表</title> 6 <link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css?1.1.11"> 7 </head> 8 <body> 9 <div style="width: 700px; margin: 30px auto">10 <a class="btn btn-default" href="/school/add_cls/" style="margin-bottom: 10px">添加班级</a>11 <table class="table table-hover" border="1" cellspacing="0">12 <thead>13 <tr>14 <th>ID</th>15 <th>班级</th>16 <th>操作</th>17 </tr>18 </thead>19 <tbody>20 {% for item in cls_list %}21 <tr>22 <td>{{ item.id }}</td>23 <td>{{ item.title }}</td>24 <td><a href="/school/edit_cls/{{ item.id }}">编辑</a></td>25 </tr>26 {% endfor %}27 </tbody>28 </table>29 </div>30 </body>31 </html>


1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>添加班级</title> 6 </head> 7 <body> 8 <h1>添加班级</h1> 9 <form action="/school/add_cls/" method="post">10 {% csrf_token %}11 <p>12 {{ obj.title }} {{ obj.errors.title.0 }}13 </p>14 <input type="submit" value="提交">15 </form>16 </body>17 </html>


1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>编辑班级</title> 6 </head> 7 <body> 8 <h1>编辑班级</h1> 9 <form action="/school/edit_cls/{{ nid }}" method="post">10 {% csrf_token %}11 <p>12 {{ obj.title }} {{ obj.errors.title.0 }}13 </p>14 <input type="submit" value="提交">15 </form>16 </body>17 </html>
teachers:


1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>教师列表</title> 6 <link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css?1.1.11"> 7 </head> 8 <body> 9 <div style="width: 700px; margin: 30px auto">10 <a class="btn btn-default" href="/school/add_tch/" style="margin-bottom: 10px">添加教师</a>11 <table class="table table-hover" border="1" cellspacing="0">12 <thead>13 <tr>14 <th>ID</th>15 <th>姓名</th>16 <th>任教班级</th>17 <th>操作</th>18 </tr>19 </thead>20 <tbody>21 {% for item in tch_list %}22 <tr>23 <td>{{ item.id }}</td>24 <td>{{ item.name }}</td>25 <td>26 {% for row in item.t2c.all %}27 <span style="border: solid gray 1px">{{ row.title }}</span>28 {% endfor %}29 </td>30 <td><a href="/school/edit_tch/{{ item.id }}">编辑</a></td>31 </tr>32 {% endfor %}33 </tbody>34 </table>35 </div>36 </body>37 </html>


1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>添加教师</title> 6 <link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css?1.1.11"> 7 </head> 8 <body> 9 <div style="width: 500px; margin: 20px auto">10 <h3 style="width: 100px; margin: 10px auto">添加教师</h3>11 <form class="form-horizontal" action="/school/add_tch/" method="post">12 {% csrf_token %}13 <div class="form-group">14 <label class="col-sm-2 control-label">姓名</label>15 <div class="col-sm-10">16 {{ obj.name }} {{ obj.errors.name.0 }}17 </div>18 </div>19 <div class="form-group">20 <label class="col-sm-2 control-label">班级</label>21 <div class="col-sm-10">22 {{ obj.t2c }} {{ obj.errors.t2c.0 }}23 </div>24 </div>25 <div class="form-group">26 <div class="col-sm-offset-2 col-sm-10">27 <input type="submit" class="btn btn-default" value="提交"></input>28 </div>29 </div>30 </form>31 </div>32 </body>33 </html>


1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>编辑教师</title> 6 <link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css?1.1.11"> 7 </head> 8 <body> 9 <div style="width: 500px; margin: 20px auto">10 <h3 style="width: 100px; margin: 10px auto">编辑教师</h3>11 <form class="form-horizontal" action="/school/edit_tch/{{ nid }}" method="post">12 {% csrf_token %}13 <div class="form-group">14 <label class="col-sm-2 control-label">姓名</label>15 <div class="col-sm-10">16 {{ obj.name }} {{ obj.errors.name.0 }}17 </div>18 </div>19 20 <div class="form-group">21 <label class="col-sm-2 control-label">班级</label>22 <div class="col-sm-10">23 {{ obj.t2c }} {{ obj.errors.t2c.0 }}24 </div>25 </div>26 <div class="form-group">27 <div class="col-sm-offset-2 col-sm-10">28 <input type="submit" class="btn btn-default" value="提交"></input>29 </div>30 </div>31 </form>32 </div>33 </body>34 </html>
4. 数据不能同步
在班级表中新增一条记录
在教师表中新添加一名教师,发现无法获取上一步新增记录
5. 原因分析
在添加教师时,请求方式为GET,html标签由Form组件自动生成,其中的数据也是由Form组件提供
而TchForm作为一个类,在project运行起来后,其中的name和t2c字段都是类的变量,其只执行一次,就将数据保存在内存中,无论之后生成多少个TchForm对象,其中的字段的值都不变。
所以会出现教师表中的班级多选列表无法动态更新。
二、解决上述bug的方法
每次更新数据库后重启project,让Form类重新初始化,能够让数据更新,但这显然是不切实际的。
知道了bug的根源,我们可以尝试让每次生成TchForm对象时就更新数据:
方法一
1. 利用 __init__将数据库操作放入对象变量中


1 #教师表单验证规则 2 class TchForm(Form): 3 name = fields.CharField(max_length=16, min_length=2, widget=widgets.TextInput(attrs={'class': 'form-control'})) 4 t2c = fields.MultipleChoiceField( 5 # choices=models.Classes.objects.values_list('id', 'title'), 6 widget=widgets.SelectMultiple(attrs={'class': 'form-control'}) 7 ) 8 9 def __init__(self, *args, **kwargs): # 自定义__init__10 super(TchForm, self).__init__(*args, **kwargs) # 调用父类的__init__11 self.fields['t2c'].choices = models.Classes.objects.values_list('id', 'title') # 为字段t2c的choices赋值
2. 验证
在班级表中新增一条记录
再在教师表中添加
方法二
1. 利用django.forms.models模块中的queryset连接数据库


1 #教师表单验证规则 2 from django.forms import models as form_models # 导入django.forms.models 3 class TchForm(Form): 4 name = fields.CharField(max_length=16, min_length=2, widget=widgets.TextInput(attrs={'class': 'form-control'})) 5 #重新定义字段 6 t2c = form_models.ModelMultipleChoiceField( 7 # choices=models.Classes.objects.values_list('id', 'title'), 8 queryset=models.Classes.objects.all(), # 利用queryset连接数据库,只能连接object类型 9 widget=widgets.SelectMultiple(attrs={'class': 'form-control'})10 )
2. 验证
由于TchForm类中,queryset只能连接object类型,所以,需要设置models.py中的Classes类的返回值。


1 class Classes(models.Model):2 title = models.CharField(max_length=32)3 4 def __str__(self):5 return self.title
在班级表中新增一条记录
再在教师表中添加
以上是分享两种方法解决Form表单数据无法动态刷新的方法的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

查看django版本步骤:1、打开终端或命令提示符窗口;2、确保已经安装了Django,如果没有安装Django,可以使用包管理工具来进行安装,输入pip install django命令即可;3、安装完成后,可以使用python -m django --version来查看Django的版本。

Django和Flask都是PythonWeb框架中的佼佼者,它们都有着自己的优点和适用场景。本文将对这两个框架进行对比分析,并提供具体的代码示例。开发简介Django是一个全功能的Web框架,它的主要目的是为了快速开发复杂的Web应用。Django提供了许多内置的功能,比如ORM(对象关系映射)、表单、认证、管理后台等。这些功能使得Django在处理大型

Django是一个完整的开发框架,该框架涵盖了Web开发生命周期的各个方面。目前,这个框架是全球范围内最流行的Web框架之一。如果你打算使用Django来构建自己的Web应用程序,那么你需要了解Django框架的优点和缺点。以下是您需要知道的一切,包括具体代码示例。Django优点:1.快速开发-Djang可以快速开发Web应用程序。它提供了丰富的库和内

查看django版本的方法:1、通过命令行查看,在终端或命令行窗口中输入“python -m django --version”命令;2、在Python交互式环境中查看,输入“import django print(django.get_version())”代码;3、检查Django项目的设置文件,找到名为INSTALLED_APPS的列表,其中包含已安装的应用程序信息。

如何升级Django版本:步骤和注意事项,需要具体代码示例引言:Django是一个功能强大的PythonWeb框架,它持续地进行更新和升级,以提供更好的性能和更多的功能。然而,对于使用较旧版本Django的开发者来说,升级Django可能会面临一些挑战。本文将介绍如何升级Django版本的步骤和注意事项,并提供具体的代码示例。一、备份项目文件在升级Djan

django是后端。详细介绍:尽管Django主要是一个后端框架,但它与前端开发密切相关。通过Django的模板引擎、静态文件管理和RESTful API等功能,前端开发人员可以与后端开发人员协作,共同构建功能强大、可扩展的Web应用程序。

区别是:1、Django 1.x系列:这是Django的早期版本,包括1.0、1.1、1.2、1.3、1.4、1.5、1.6、1.7、1.8和1.9等版本。这些版本主要提供基本的Web开发功能;2、Django 2.x系列:这是Django的中期版本,包括2.0、2.1、2.2等版本;3、Django 3.x系列:这是Django的最新版本系列,包括3.0、3等版本。

如何使用JavaScript实现表单的输入框内容实时校验功能?在很多网页应用中,表单是用户与系统之间最常用的交互方式。然而,用户输入的内容往往需要进行有效性校验,以确保数据的准确性和完整性。在这篇文章中,我们将学习如何使用JavaScript实现表单的输入框内容实时校验功能,并提供具体的代码示例。创建表单首先,我们需要在HTML中创建一个简单的表
