[oldboy-django][2深入django]老师管理 -- form表单如何生成多选框标签,多选框的默认值显示,以及多选框数据插入到数据库,多选框数据更改到数据库
1 form表单如何生成多选框(包含了多选框可选择内容)
- Form设置班级输入框为 select多选 - 多选 class TeacherForm(Form): name = fields.CharField(max_length=16, widget=widgets.TextInput(attrs={'class': 'form-control'}) ) cls = fields.MultipleChoiceField( choices=models.Classes.objects.values_list('id', 'title'), widget=widgets.SelectMultiple(attrs={'class': 'form-control'}) )
2 上面存在bug:刷新页面无法动态刷新数据库数据
# BUG:页面刷新时,无法动态显示数据库内容 分别打开添加老师(或者学生)的页面,和添加班级的页面, 然后再添加班级页面新添加一个班级。 刷选添加老师(或者学生)页面,发现班级下拉框并没有动态增加刚才新增加的班级。 原因分析:出现在class TeacherForm和StudentForm定义上,以TeacherForm为例 class TeacherForm(Form): name = fields.CharField(max_length=16, widget=widgets.TextInput(attrs={'class': 'form-control'}) ) cls = fields.MultipleChoiceField( choices=models.Classes.objects.values_list('id', 'title'), widget=widgets.SelectMultiple(attrs={'class': 'form-control'}) ) 在实例化一个TeacherForm对象时,由于name, cls为类变量,所以这两个类变量只要第一次生成后, 后面实例化对象时,这两个变量是不会改变的。 在调用父类init函数时,会将cls, name放到父类的self.fields里面 self.fields = {'name': name, 'cls': cls} 因此解决办法出来了,在每一次实例化对象时,再获取数据库的值给cls, 重新刷新self.fields里面的cls字段内容 class TeacherForm(Form): name = fields.CharField(max_length=16, widget=widgets.TextInput(attrs={'class': 'form-control'}) ) cls = fields.MultipleChoiceField( choices=models.Classes.objects.values_list('id', 'title'), # 多选这个可不能删,因为下面的init修改的不是这里 widget=widgets.SelectMultiple(attrs={'class': 'form-control'}) ) def __init__(self, *args, **kwargs): super(TeacherForm, self).__init__(*args, **kwargs) self.fields['cls'].widget.choices = models.Classes.objects.values_list('id', 'title')
3 多选框的内容如何插入数据库
obj = TeacherForm(request.POST) if obj.is_valid(): print(obj.cleaned_data) # 多对多关系插入数据库,主要是插入teacher表,和第三张表 class_list = obj.cleaned_data.pop('cls') print(class_list) teacher = models.Teacher.objects.create(**obj.cleaned_data) teacher.cls.add(*class_list)
4 多选框的默认显示
initial中的多选框key的value必须是列表
def edit_teacher(request, nid): if request.method == "GET": row = models.Teacher.objects.filter(id=nid).first() class_ids = row.cls.values_list('id') class_id_list = list(zip(*class_ids))[0] if list(zip(*class_ids)) else [] obj = TeacherForm(initial={'name': row.name, 'cls': class_id_list}) # obj = TeacherForm(initial={'name': row.name, 'cls': [1,2]}) return render(request, 'app01_edit_teacher.html', {'obj': obj, 'nid': nid})
5 多选框数据更改到数据库
obj = TeacherForm(request.POST) if obj.is_valid(): print(obj.cleaned_data) models.Teacher.objects.filter(id=nid).update(name=obj.cleaned_data['name']) teacher = models.Teacher.objects.filter(id=nid).first() teacher.cls.set(obj.cleaned_data['cls'])
6 老师管理
6.1 查看老师列表
6.1.1 前端
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css"> <link rel="stylesheet" href="/static/plugins/font-awesome-4.7.0/css/font-awesome.css"> </head> <body> <h4>老师管理</h4> <p> <a href="/app01/add_teacher" class="btn btn-primary">添加</a> </p> <table class="table table-striped table-bordered table-hover table-condensed"> <thead> <tr> <th>ID</th> <th>姓名</th> <th>班级</th> <th>操作</th> </tr> </thead> <tbody> {% for item in teacher_list %} <tr> <td>{{ item.id }}</td> <td>{{ item.name }}</td> <td> {% for x in item.cls.values_list %} {{ x.1}} {% endfor %} </td> <td> <a href="/app01/edit_teacher/nid={{ item.id }}" class="glyphicon glyphicon-pencil">编辑</a>| <a href="/app01/del_teacher/nid={{ item.id }}" class="glyphicon glyphicon-trash">删除</a> </td> {#点击删除是一个get请求,要想告诉服务器id,可以通过url get请求获取,或者url匹配到传递给视图#} </tr> {% endfor %} </tbody> </table> <nav aria-label="Page navigation"> <ul class="pagination"> {{ page_info.pager|safe }} </ul> </nav> </body> </html>
6.1.2 视图
def teachers(request): teacher_list = models.Teacher.objects.all() return render(request, 'app01_teacher_list.html', {'teacher_list': teacher_list})
6.2 增加老师
6.2.1 前端
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css"> <link rel="stylesheet" href="/static/plugins/font-awesome-4.7.0/css/font-awesome.css"> </head> <body> <div style="width:500px;margin:0 auto"> <h4 style="margin-left: 25px;">添加老师</h4> <form class="form-horizontal" action="/app01/add_teacher" 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.0 }} </div> </div> <div class="form-group"> <label class="col-sm-2 control-label">班级:</label> <div class="col-sm-10"> {{ obj.cls }} {{ obj.errors.cls.0 }} </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <input type="submit" class="btn btn-default" value="提交"/> </div> </div> </form> </div> </body> </html>
6.2.2 视图
def add_teacher(request): if request.method == "GET": obj = TeacherForm() return render(request, 'app01_add_teacher.html', {'obj': obj}) else: obj = TeacherForm(request.POST) if obj.is_valid(): print(obj.cleaned_data) # 多对多关系插入数据库,主要是插入teacher表,和第三张表 class_list = obj.cleaned_data.pop('cls') print(class_list) teacher = models.Teacher.objects.create(**obj.cleaned_data) teacher.cls.add(*class_list) return redirect('/app01/teachers') else: print('POST=', request.POST) print('errors=', obj.errors) return render(request, 'app01_teacher_list.html', {'obj': obj})
6.3 编辑老师
6.3.1 前端
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/app01/edit_teacher/nid={{ nid }}" method="POST"> {% csrf_token %} {{ obj.name }} {{ obj.cls }} <p><input type="submit" value="提交"></p> </form> </body> </html>
6.3.2 视图
def edit_teacher(request, nid): if request.method == "GET": row = models.Teacher.objects.filter(id=nid).first() class_ids = row.cls.values_list('id') class_id_list = list(zip(*class_ids))[0] if list(zip(*class_ids)) else [] obj = TeacherForm(initial={'name': row.name, 'cls': class_id_list}) # obj = TeacherForm(initial={'name': row.name, 'cls': [1,2]}) return render(request, 'app01_edit_teacher.html', {'obj': obj, 'nid': nid}) else: print('hello') obj = TeacherForm(request.POST) if obj.is_valid(): print(obj.cleaned_data) models.Teacher.objects.filter(id=nid).update(name=obj.cleaned_data['name']) teacher = models.Teacher.objects.filter(id=nid).first() teacher.cls.set(obj.cleaned_data['cls']) return redirect('/app01/teachers') else: return render(request, 'app01_edit_teacher.html', {'obj': obj, 'nid': nid})