实现简单数据库数据页面展示,增加,删除,修改,查询,重置(5个)功能可用
效果展示:
1.建立模板
使用bootstrap中的模板,创建基类模板与主页界面模板
base.html:提供模板使用,通过引用静态资源,以及{% block %} 进行占位
{% load static %} #引用css静态资源的位置,如下css代码只需提供位置 <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! --> <meta name="description" content=""> <meta name="author" content=""> <title>{% block title %}Dashboard Template for Bootstrap{% endblock %}</title> #使用{% block %}进行挖坑,模板继承使用自定义的变量替代 <!-- Bootstrap core CSS --> <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> <!-- Custom styles for this template --> <link href="{% static 'teacher/css/dashboard.css' %}" rel="stylesheet"> <!-- Just for debugging purposes. Don't actually copy these 2 lines! --> <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries --> <!--[if lt IE 9]> <script src="https://cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script> <script src="https://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script> <![endif]--> </head> <body> <nav class="navbar navbar-inverse navbar-fixed-top"> <div class="container-fluid"> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">CRM 管理系统</a> </div> <div id="navbar" class="navbar-collapse collapse"> <ul class="nav navbar-nav navbar-right"> <li><a href="#">后台</a></li> <li><a href="#">论坛</a></li> <li><a href="#">学员</a></li> <li><a href="#">退出</a></li> </ul> </div> </div> </nav> <div class="container-fluid"> <div class="row"> <div class="col-sm-3 col-md-2 sidebar"> <ul class="nav nav-sidebar"> <li class="active"><a href="#">学生管理 <span class="sr-only">(current)</span></a></li> <li><a href="#">订单管理</a></li> <li><a href="#">课程管理</a></li> <li><a href="#">班级管理</a></li> </ul> <ul class="nav nav-sidebar"> <li><a href="">系统设置</a></li> <li><a href="">菜单管理</a></li> <li><a href="">权限管理</a></li> </ul> </div> <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main"> <h2 class="sub-header">{% block section %}Section title{% endblock %}</h2> #对section进行挖坑 {% block content %} #对content进行挖坑 <div class="table-responsive"> <table class="table table-striped"> <thead> <tr> <th>#</th> <th>Header</th> <th>Header</th> <th>Header</th> <th>Header</th> </tr> </thead> <tbody> <tr> <td>1,001</td> <td>Lorem</td> <td>ipsum</td> <td>dolor</td> <td>sit</td> </tr> <tr> <td>1,002</td> <td>amet</td> <td>consectetur</td> <td>adipiscing</td> <td>elit</td> </tr> <tr> <td>1,003</td> <td>Integer</td> <td>nec</td> <td>odio</td> <td>Praesent</td> </tr> <tr> <td>1,003</td> <td>libero</td> <td>Sed</td> <td>cursus</td> <td>ante</td> </tr> <tr> <td>1,004</td> <td>dapibus</td> <td>diam</td> <td>Sed</td> <td>nisi</td> </tr> <tr> <td>1,005</td> <td>Nulla</td> <td>quis</td> <td>sem</td> <td>at</td> </tr> <tr> <td>1,006</td> <td>nibh</td> <td>elementum</td> <td>imperdiet</td> <td>Duis</td> </tr> <tr> <td>1,007</td> <td>sagittis</td> <td>ipsum</td> <td>Praesent</td> <td>mauris</td> </tr> <tr> <td>1,008</td> <td>Fusce</td> <td>nec</td> <td>tellus</td> <td>sed</td> </tr> <tr> <td>1,009</td> <td>augue</td> <td>semper</td> <td>porta</td> <td>Mauris</td> </tr> <tr> <td>1,010</td> <td>massa</td> <td>Vestibulum</td> <td>lacinia</td> <td>arcu</td> </tr> <tr> <td>1,011</td> <td>eget</td> <td>nulla</td> <td>Class</td> <td>aptent</td> </tr> <tr> <td>1,012</td> <td>taciti</td> <td>sociosqu</td> <td>ad</td> <td>litora</td> </tr> <tr> <td>1,013</td> <td>torquent</td> <td>per</td> <td>conubia</td> <td>nostra</td> </tr> <tr> <td>1,014</td> <td>per</td> <td>inceptos</td> <td>himenaeos</td> <td>Curabitur</td> </tr> <tr> <td>1,015</td> <td>sodales</td> <td>ligula</td> <td>in</td> <td>libero</td> </tr> </tbody> </table> </div> {% endblock %} </div> </div> </div> <!-- Bootstrap core JavaScript ================================================== --> <!-- Placed at the end of the document so the pages load faster --> <script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"></script> <script>window.jQuery || document.write('<script src="../../assets/js/vendor/jquery.min.js"></script>')</script> <script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> </body> </html>
通过继承base类的,通过自定义{% block %}块进行自定义页面。
{% extends 'teacher/base.html' %} {% block title%}学生列表{% endblock %} {% block section %}{{ section }} {% endblock %} {% block content %} <div class="table-responsive"> <form class="form-inline" style="margin-bottom: 10px" action=""> #默认提交为get <div class="form-group"> <input type="text" class="form-control" name="search" id="exampleInputName2" placeholder="姓名,qq,电话"> </div> <button type="submit" class="btn btn-default" value="{{ search }}">搜索</button> #添加value选项时,会保存现场 <a class="btn btn-primary" role="button" href="{% url 'teacher:student_add' %}">添加</a> <a class="btn btn-primary" role="button" href="{% url 'teacher:students' %}">重置</a> </form> <table class="table table-striped table-bordered"> <thead> <tr> <th>序号</th> <th>姓名</th> <th>年龄</th> <th>性别</th> <th>qq</th> <th>电话</th> <th>操作</th> </tr> </thead> <tbody> {% for stu in students %} <tr> <td>{{ forloop.counter }}</td> <td>{{ stu.name }}</td> <td>{{ stu.age }}</td> <td>{{ stu.sex }}</td> <td>{{ stu.qq|default:'未填' }}</td> <td>{{ stu.phone|default:'未填' }}</td> <td> <a href="{% url 'teacher:student_edit' stu.id %}" class="btn btn-primary btn-xs active" role="button">编辑</a> <a href="{% url 'teacher:delete' %}?pk={{ stu.id }}" class="btn btn-danger btn-xs active" role="button">删除</a> #删除是向后端传递参数 </td> </tr> {% endfor %} </tbody> </table> </div> {% endblock %}
2.学生列表页面,搜索功能
#
urls.py中添加:
path('students/', views.students, name='students'),
view.py中添加:
def students(request): section = '学生列表' #获取查询参数 search = request.GET.get('search','').strip() if search: if search.isdigit(): sts = Student.objects.filter(Q(qq=search)|Q(phone=search),is_deleted=False).order_by('-e_time') #是qq或者电话 else: sts = Student.objects.filter(name__contains=search,is_deleted=False).order_by('-e_time') else: sts = Student.objects.filter(is_deleted=False).order_by('-e_time') return render(request,'teacher/students.html',context= {'students':sts, 'section':section, 'search':search })
3.删除功能
urls.py中增加:
path('delete/',views.del_student,name='delete'),
views.py中添加:接收到参数后,进行数据库操作,返回主页面
def del_student(request): pk = request.GET.get('pk',None) if pk: student = Student.objects.get(pk=pk) student.is_deleted =True student.save() return redirect(reverse('teacher:students'))
4.添加学生
urls.py中增加:
path('student_add/',views.add_student,name='student_add'),
views.py中添加:点击‘添加’按钮后,GET请求跳转到student_edit.html。当通过页面添加保存后提交POST请求进行下一步。由于采集到身份证信息,学校名称等StudentDetail表
中的字段,需要先创建Student实例,后创建StudentDetail实例。
def add_student(request): section = '添加学生' grades = Grade.objects.all() if request.method == 'GET': return render(request,'teacher/student_edit.html',context={ 'section':section, 'grades':grades, #传递这个参数是为了进行页面渲染 }) if request.method == 'POST': data = { 'name':request.POST.get('name'), 'age':request.POST.get('age'), 'sex':request.POST.get('sex'), 'qq':request.POST.get('qq'), 'phone':request.POST.get('phone'), 'grade_id':request.POST.get('grade'), } student = Student(**data) student.save() student_detail = StudentDetail( num = request.POST.get('num'), college= request.POST.get('college'), student=student, ) student_detail.save() return redirect(reverse('teacher:students'))
student_edit.html 代码为:
{% extends 'teacher/base.html' %} {% block title %}添加学生{% endblock %} {#{% load customer_tags %}#} {% block section %} {{ section }}{% endblock %} {% block content %} <form class="form-horizontal" method="post"> {% csrf_token %} <div class="form-group"> <label for="name" class="col-sm-2 control-label">姓名</label> <div class="col-sm-3"> <input type="text" class="form-control" id="name" name="name" value="{{ student.name }}"> </div> </div> <div class="form-group"> <label for="age" class="col-sm-2 control-label">年龄</label> <div class="col-sm-3"> <input type="text" class="form-control" id="age" name="age" value="{{ student.age }}"> </div> </div> <div class="form-group"> <label for="sex" class="col-sm-2 control-label">性别</label> <div class="col-sm-10"> <label class="radio-inline"> <input type="radio" name="sex" {% if student.sex == 1 %}checked{% endif %} id="inlineRadio1" value="1"> 男 </label> <label class="radio-inline"> <input type="radio" name="sex"{% if student.sex == 0 %}checked{% endif %} id="inlineRadio2" value="0"> 女 </label> </div> </div> <div class="form-group"> <label for="qq" class="col-sm-2 control-label">QQ</label> <div class="col-sm-3"> <input type="text" class="form-control" id="qq" name="qq" value="{{ student.qq }}"> </div> </div> <div class="form-group"> <label for="phone" class="col-sm-2 control-label">电话</label> <div class="col-sm-3"> <input type="text" class="form-control" id="phone" name="phone" value="{{ student.phone|default:'' }}"> </div> </div> <div class="form-group"> <label for="grade" class="col-sm-2 control-label">年级</label> <div class="col-sm-3"> <select class="form-control" name="grade"> <option value="">未选班级</option> {# {% grade_option as grades %}#} {% for grade in grades %} <option {% if student.grade_id == grade.id %}selected{% endif %} value="{{ grade.id }}">{{ grade.name }}</option> {% endfor %} </select> </div> </div> <div class="form-group"> <label for="num" class="col-sm-2 control-label">身份证</label> <div class="col-sm-3"> <input type="text" class="form-control" id="num" name="num" value="{{ student.studentdetail.num|default:'' }}"> </div> </div> <div class="form-group"> <label for="college" class="col-sm-2 control-label">毕业院校</label> <div class="col-sm-3"> <input type="text" class="form-control" id="college" name="college" value="{{ student.studentdetail.college|default:'' }}"> </div> </div> <button type="submit" class="btn btn-primary">提交</button> </form> {% endblock %}
5.
编辑学生信息
urls.py中添加:
path('student_edit/<int:pk>/',views.edit_student,name='student_edit'),
views.py中添加:
编辑修改学生信息,为获取已知pk的记录,如果修改以后学生详情变化,则不能保存StudentDetail表。需要先创建StudentDetail实例。在进行保存。
def edit_student(request,pk): student = Student.objects.get(pk =pk) grades = Grade.objects.all() if request.method == 'GET': return render(request,'teacher/student_edit.html', context={ 'student':student, 'grades':grades, }) if request.method == 'POST': student.name = request.POST.get('name') student.age = request.POST.get('age') student.qq = request.POST.get('qq') student.sex = request.POST.get('sex') student.phone = request.POST.get('phone') student.grade_id = request.POST.get('grade') student.save() #判断一下,student有没有详情 try: student_detail = student.studentdetail except: student_detail = StudentDetail() student_detail.student = student student_detail.num = request.POST.get('num') student_detail.college = request.POST.get('college') student_detail.save() return redirect(reverse('teacher:students'))
6.使用标签渲染年级字段
在customer_tags.py 中添加
@register.simple_tag() def grade_option(): grades = Grade.objects.all() return grades
在student_edit.html中引用,引用customer_tags中的grades,就能够在views.py中不传递grade参数也能够解析{% grade.name %}
{% load customer_tags %} <form class="form-horizontal" method="post"> {% csrf_token %} <div class="form-group"> <label for="grade" class="col-sm-2 control-label">年级</label> <div class="col-sm-3"> <select class="form-control" name="grade"> <option value="">未选班级</option> {% grade_option as grades %} {% for grade in grades %} <option {% if student.grade_id == grade.id %}selected{% endif %} value="{{ grade.id }}">{{ grade.name }}</option> {% endfor %} </select> </div> </div> <button type="submit" class="btn btn-primary">提交</button> </form> {% endblock %}
view中的变化如下(可以注释如下部分)
def add_student(request): section = '添加学生' # grades = Grade.objects.all() if request.method == 'GET': return render(request,'teacher/student_edit.html',context={ 'section':section, # 'grades':grades, }) def edit_student(request,pk): student = Student.objects.get(pk =pk) # grades = Grade.objects.all() if request.method == 'GET': return render(request,'teacher/student_edit.html', context={ 'student':student, # 'grades':grades, })