框架----Django之Form提交验证(二)
一、Form提交验证之(学生表、老师表、班级表)的添加和编辑实现案例
1. 浏览器访问
http://127.0.0.1:8000/student_list/ http://127.0.0.1:8000/teacher_list/ http://127.0.0.1:8000/class_list/
2. models
1 from django.db import models 2 3 class Classes(models.Model): 4 title = models.CharField(max_length=32) 5 6 7 class Student(models.Model): 8 name = models.CharField(max_length=32) 9 email = models.CharField(max_length=32) 10 age = models.IntegerField() 11 cls = models.ForeignKey('Classes') 12 13 14 class Teacher(models.Model): 15 tname = models.CharField(max_length=32) 16 c2t = models.ManyToManyField('Classes')
3. urls
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^class_list/', views.class_list), url(r'^add_class/', views.add_class), url(r'^edit_class/(\d+)/', views.edit_class), url(r'^student_list/', views.student_list), url(r'^add_student/', views.add_student), url(r'^edit_student/(\d+)/', views.edit_student), url(r'^teacher_list/', views.teacher_list), url(r'^add_teacher/', views.add_teacher), url(r'^edit_teacher/(\d+)/', views.edit_teacher), url(r'^test/', views.test), ]
4. views
1 from django.shortcuts import render,redirect,HttpResponse 2 from app01 import models 3 from django.forms import Form 4 from django.forms import fields 5 from django.forms import widgets 6 7 8 # **************************班级信息************************** 9 class ClassForm(Form): 10 title = fields.RegexField('全栈\d+') 11 12 def class_list(request): 13 cls_list = models.Classes.objects.all() 14 return render(request,'class_list.html',{'cls_list':cls_list}) 15 16 def add_class(request): 17 if request.method == "GET": 18 obj = ClassForm() 19 return render(request,'add_class.html',{'obj': obj}) 20 else: 21 obj = ClassForm(request.POST) 22 if obj.is_valid(): 23 # obj.cleaned_data # 字典 24 # 数据库创建一条数据 25 # print(obj.cleaned_data) 26 # models.Classes.objects.create(title=obj.cleaned_data['tt']) 27 28 models.Classes.objects.create(**obj.cleaned_data) 29 return redirect('/class_list/') 30 return render(request,'add_class.html',{'obj': obj}) 31 32 def edit_class(request,nid): 33 if request.method == "GET": 34 row = models.Classes.objects.filter(id=nid).first() 35 # 让页面显示初始值 36 # obj = ClassForm(data={'title': 'asdfasdfasdfas'}) 37 obj = ClassForm(initial={'title': row.title}) 38 return render(request,'edit_class.html',{'nid': nid,'obj':obj}) 39 else: 40 obj = ClassForm(request.POST) 41 if obj.is_valid(): 42 models.Classes.objects.filter(id=nid).update(**obj.cleaned_data) 43 return redirect('/class_list/') 44 return render(request,'edit_class.html',{'nid': nid,'obj':obj}) 45 46 47 48 # **************************学生信息************************** 49 class StudentForm(Form): 50 name = fields.CharField( 51 min_length=2, 52 max_length=6, 53 widget=widgets.TextInput(attrs={'class': 'form-control'}) 54 ) 55 email = fields.EmailField(widget=widgets.TextInput(attrs={'class': 'form-control'})) 56 age = fields.IntegerField(min_value=18,max_value=25,widget=widgets.TextInput(attrs={'class': 'form-control'})) 57 cls_id = fields.IntegerField( 58 # widget=widgets.Select(choices=[(1,'上海'),(2,'北京')]) 59 #widgets 定义生成的标签类型 select下来菜单标签从数据库取值时使用values_list 60 widget=widgets.Select(choices=models.Classes.objects.values_list('id','title'),attrs={'class': 'form-control'}) 61 ) 62 63 def student_list(request): 64 stu_list = models.Student.objects.all() 65 return render(request,'student_list.html',{'stu_list':stu_list}) 66 67 def add_student(request): 68 if request.method == "GET": 69 obj = StudentForm() 70 return render(request,'add_student.html',{'obj':obj}) 71 else: 72 obj = StudentForm(request.POST) 73 if obj.is_valid(): 74 models.Student.objects.create(**obj.cleaned_data) 75 return redirect('/student_list/') 76 return render(request,'add_student.html',{'obj':obj}) 77 78 def edit_student(request,nid): 79 if request.method == "GET": 80 row = models.Student.objects.filter(id=nid).values('name','email','age','cls_id').first() 81 obj = StudentForm(initial=row) #initial 只有HTML标签 82 return render(request,'edit_student.html',{'nid':nid,'obj': obj}) 83 else: 84 obj = StudentForm(request.POST) 85 if obj.is_valid(): 86 models.Student.objects.filter(id=nid).update(**obj.cleaned_data) 87 return redirect('/student_list/') 88 return render(request,'edit_student.html',{'nid':nid,'obj': obj}) 89 90 91 92 # **************************老师信息************************** 93 from django.forms import models as form_model # 导入这个models as form_model 模块 94 class TeacherForm(Form): 95 tname = fields.CharField(min_length=2) 96 97 # xx = form_model.ModelMultipleChoiceField(queryset=models.Classes.objects.all()) 98 99 xx = fields.MultipleChoiceField( 100 # choices=models.Classes.objects.values_list('id','title'), # 写了下面的那个BUG解决这条就不用写 101 widget=widgets.SelectMultiple 102 ) 103 def __init__(self,*args,**kwargs): # 解决刷新无法动态显示数据库内容的BUG 104 super(TeacherForm,self).__init__(*args,**kwargs) 105 self.fields['xx'].choices = models.Classes.objects.values_list('id','title') 106 107 def teacher_list(request): 108 tea_list = models.Teacher.objects.all() 109 return render(request,'teacher_list.html',{'tea_list':tea_list}) 110 111 def add_teacher(request): 112 if request.method == 'GET': 113 obj = TeacherForm() 114 return render(request,'add_teacher.html',{'obj':obj}) 115 else: 116 obj = TeacherForm(request.POST) 117 if obj.is_valid(): 118 xx = obj.cleaned_data.pop('xx') # pop 剔除,去掉 119 row = models.Teacher.objects.create(**obj.cleaned_data) 120 row.c2t.add(*xx) #[1,2] 121 return redirect('/teacher_list/') 122 return render(request,'add_teacher.html',{'obj':obj}) 123 124 def edit_teacher(request,nid): 125 if request.method == 'GET': 126 row = models.Teacher.objects.filter(id=nid).first() 127 class_ids = row.c2t.values_list('id') 128 # print(class_ids) 129 # id_list = [] 130 id_list = list(zip(*class_ids))[0] if list(zip(*class_ids)) else [] # 这是个三元表达式 if 后面的如果为真就执行if前面的,否则就执行else后面的------zip是python内置函数 131 # obj = TeacherForm(initial={'tname':row.tname,'xx':[1,2,3]}) 132 obj = TeacherForm(initial={'tname': row.tname, 'xx': id_list}) # initial 初始值(也就是默认值,这里要编辑的对象输入框内要有默认的老师,select下拉框内要有默认的任教班级) 133 return render(request,'edit_teacher.html',{'obj':obj,'nid':nid}) 134 else: 135 obj = TeacherForm(request.POST) 136 if obj.is_valid(): 137 xx = obj.cleaned_data.pop('xx') # pop 剔除,去掉 138 row = models.Teacher.objects.filter(id=nid).update(**obj.cleaned_data) 139 row.c2t.add(*xx) 140 return redirect('/teacher_list/') 141 return render(request, 'edit_teacher.html', {'obj': obj}) 142 143 144 145 # **************************测试************************** 146 from django.core.exceptions import ValidationError 147 148 class TestForm(Form): 149 user = fields.CharField(validators=[]) 150 pwd = fields.CharField() 151 152 def clean_user(self): 153 v = self.cleaned_data['user'] 154 if models.Student.objects.filter(name=v).count(): 155 raise ValidationError('用户名已经存在') 156 return self.cleaned_data['user'] 157 158 def clean_pwd(self): 159 return self.cleaned_data['pwd'] 160 161 def clean(self): 162 # user = self.cleaned_data.get('user') 163 # email = self.cleaned_data.get('email') 164 # if models.Student.objects.filter(user=user,email=email).count(): 165 # raise ValidationError('用户名和邮箱联合已经存在') 166 return self.cleaned_data 167 168 # def _post_clean(self): 169 # """ 170 # An internal hook for performing additional cleaning after form cleaning 171 # is complete. Used for model validation in model forms. 172 # """ 173 # pass 174 175 176 177 def test(request): 178 obj = TestForm(initial={'t3':[2,3]}) #默认值为2,3 179 obj.is_valid() 180 return render(request,'test.html',{'obj':obj})
5. templates
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 <a href="/add_student/">添加</a> 10 <ul> 11 {% for row in stu_list %} 12 <li> 13 {{ row.name }}-{{ row.email }}-{{ row.age }}-{{ row.cls_id }}-{{ row.cls.title }} 14 <a href="/edit_student/{{ row.id }}/">编辑</a> 15 </li> 16 {% endfor %} 17 </ul> 18 </body> 19 </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 <div> 10 <a href="/add_teacher/">添加</a> 11 </div> 12 <table border="1"> 13 <thead> 14 <tr> 15 <th>ID</th> 16 <th>老师姓名</th> 17 <th>任教班级</th> 18 </tr> 19 </thead> 20 <tbody> 21 {% for row in tea_list %} 22 <tr> 23 <td>{{ row.id }}</td> 24 <td>{{ row.tname }}</td> 25 <td> 26 {% for row in row.c2t.all %} 27 {{ row.title }} 28 {% endfor %} 29 </td> 30 <td> 31 <a href="/edit_teacher/{{ row.id }}/">编辑</a> 32 </td> 33 </tr> 34 {% endfor %} 35 </tbody> 36 </table> 37 </body> 38 </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 <div> 10 <a href="/add_class/">添加</a> 11 </div> 12 <ul> 13 {% for row in cls_list %} 14 <li>{{ row.title }} <a href="/edit_class/{{ row.id }}/">编辑</a> </li> 15 {% endfor %} 16 </ul> 17 </body> 18 </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="/add_student/" method="POST"> 10 {% csrf_token %} 11 <p> 12 {{ obj.name }} 13 </p> 14 <p> 15 {{ obj.email }} 16 </p> 17 <p> 18 {{ obj.age }} 19 </p> 20 <p> 21 {{ obj.cls_id }} 22 </p> 23 <input type="submit" value="提交" /> 24 </form> 25 </body> 26 </html>
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title></title> 6 </head> 7 <body> 8 <form method="POST" action="/add_teacher/"> 9 {% csrf_token %} 10 <p> 11 姓名:{{ obj.tname }} 12 </p> 13 <p> 14 班级:{{ obj.xx }} 15 </p> 16 <input type="submit" value="提交"> 17 </form> 18 </body> 19 </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 method="POST" action="/add_class/" novalidate> 10 {% csrf_token %} 11 {{ obj.title }} {{ obj.errors.title.0 }} 12 <input type="submit" value="提交" /> 13 </form> 14 </body> 15 </html>
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title></title> 6 <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap-theme.css"/> 7 </head> 8 <body> 9 <div style="width: 500px;margin: 0 auto;"> 10 <form class="form-horizontal" method="POST" action="/edit_student/{{ nid }}/"> 11 {% csrf_token %} 12 <div class="form-group"> 13 <label class="col-sm-2 control-label">姓名:</label> 14 15 <div class="col-sm-10"> 16 {{ obj.name }} 17 </div> 18 </div> 19 <div class="form-group"> 20 <label class="col-sm-2 control-label">邮箱:</label> 21 22 <div class="col-sm-10"> 23 {{ obj.email }} 24 </div> 25 </div> 26 <div class="form-group"> 27 <label class="col-sm-2 control-label">年龄:</label> 28 29 <div class="col-sm-10"> 30 {{ obj.age }} 31 </div> 32 </div> 33 <div class="form-group"> 34 <label class="col-sm-2 control-label">班级:</label> 35 36 <div class="col-sm-10"> 37 {{ obj.cls_id }} 38 </div> 39 </div> 40 <div class="form-group"> 41 <div class="col-sm-offset-2 col-sm-10"> 42 <input type="submit" class="btn btn-default" value="提交" /> 43 </div> 44 </div> 45 </form> 46 </div> 47 </body> 48 </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 method="POST" action="/edit_teacher/{{ nid }}/"> 10 {% csrf_token %} 11 {{ obj.tname }} 12 {{ obj.xx }} 13 <input type="submit" value="提交"> 14 </form> 15 </body> 16 </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 method="POST" action="/edit_class/{{ nid }}/"> 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 {{ obj.t1 }} 9 {{ obj.t2 }} 10 {{ obj.t3 }} 11 {{ obj.t4 }} 12 {{ obj.t5 }} 13 </body> 14 </html>
6. 运行结果截图