目錄
一、無法動態更新資料的實例
1. 如下,資料庫中建立了班級表和教師表,兩張表的對應關係為「多對多」
2. views的功能有檢視、新增、編輯班級或教師表
3. html檔
4. 数据不能同步
5. 原因分析
二、解决上述bug的方法
方法一
1. 利用 __init__将数据库操作放入对象变量中
2. 验证
方法二
1. 利用django.forms.models模块中的queryset连接数据库
首頁 後端開發 Python教學 分享兩種方法解決Form表單資料無法動態刷新的方法

分享兩種方法解決Form表單資料無法動態刷新的方法

Jul 24, 2017 pm 03:37 PM
django 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)
登入後複製
models.py

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})
登入後複製
views.py

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>
登入後複製
classes.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>
登入後複製
add_classes.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>
登入後複製
edit_classes.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>
登入後複製
teachers.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>
登入後複製
add_teacher.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>
登入後複製
edit_teacher.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赋值
登入後複製
修改TchForm类

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     )
登入後複製
修改TchForm类

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
登入後複製
设置models.py中的Classes类的返回值

在班级表中新增一条记录

再在教师表中添加

 

以上是分享兩種方法解決Form表單資料無法動態刷新的方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
2 週前 By 尊渡假赌尊渡假赌尊渡假赌
倉庫:如何復興隊友
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒險:如何獲得巨型種子
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

怎麼看django版本 怎麼看django版本 Dec 01, 2023 pm 02:25 PM

怎麼看django版本

Django vs. Flask:Python Web框架的比較分析 Django vs. Flask:Python Web框架的比較分析 Jan 19, 2024 am 08:36 AM

Django vs. Flask:Python Web框架的比較分析

Django框架的優點和缺點:您需要知道的一切 Django框架的優點和缺點:您需要知道的一切 Jan 19, 2024 am 09:09 AM

Django框架的優點和缺點:您需要知道的一切

怎麼查看django版本 怎麼查看django版本 Nov 30, 2023 pm 03:08 PM

怎麼查看django版本

django是前端還是後端 django是前端還是後端 Nov 21, 2023 pm 02:36 PM

django是前端還是後端

如何升級Django版本:步驟與注意事項 如何升級Django版本:步驟與注意事項 Jan 19, 2024 am 10:16 AM

如何升級Django版本:步驟與注意事項

django版本區別是什麼 django版本區別是什麼 Nov 20, 2023 pm 04:33 PM

django版本區別是什麼

如何使用 JavaScript 實作表單的輸入框內容即時校驗功能? 如何使用 JavaScript 實作表單的輸入框內容即時校驗功能? Oct 18, 2023 am 08:47 AM

如何使用 JavaScript 實作表單的輸入框內容即時校驗功能?

See all articles