标签::hover IV com ict teacher yellow src 建表 方法
接着上一篇博客继续往下总结,上一篇博客的地址:https://www.cnblogs.com/bainianminguo/p/9189324.html
我们开始吧
这里我们就需要先看下我们设计的数据库
一、先看下数据库的设计,我们一共创建了3张表
表1为class表,他是一个单表,只有一个classes_name的字段
表2是student表,student表和class表一对多的关系,一个学生只能属于一个班级,但是一个班级可以有多个学生,所以多表是student,他通过外键【Foreignkey】去关联class表,字段为student_class
表3是teacher表,teacher表和class表是多对多的关系,一个老师可以教多个班级,同样一个班级可以被多个老师教,所以teacher表和class表是一对多的关系,通过【ManyToManyField】去关联class表,字段为teacher_class,通过ManyTomManyField是由django为我们创建第三张表,这里我们自己新建第三张表,通过Foreignkey去关联teacher表和class表
这里我们为什么为每个表定义一个__str__方法,我们先来回忆面向对象我们学过的几个特殊的方法
__doc__方法:打印这个类的描述信息,如果有的话
__module__方法:打印这个某个实例属于哪个类,或者哪个文件,或者哪个模块
__dict__方法:打印某个类或者实例有哪些方法或者变量
__str__方法:定义打印这个实例输出的值,这里我们就定义打印这个实例,就输出这个实例的名称的属性,如果没有定义,则会默认输出这个实例的内存地址
from django.db import models # Create your models here. class manager(models.Model): manager_name = models.CharField(max_length=32) manager_pwd = models.TextField(max_length=64) manager_age = models.IntegerField() def __str__(self): return self.manager_name class student(models.Model): student_name = models.CharField(max_length=32) student_class = models.ForeignKey("classes") def __str__(self): return self.student_name class classes(models.Model): classes_name = models.CharField(max_length=32,null=False) def __str__(self): return self.classes_name class teacher(models.Model): teacher_name = models.CharField(max_length=32) teacher_class = models.ManyToManyField("classes") def __str__(self): return self.teacher_name
定义好数据库后,需要执行下面的语句来初始化表
记住,如果为某个app中定义了表,则必须要在settings中定义这个app,因为上面的命令是为创建django中默认的表,因为django自己也默认定义了很多表,所以我们需要在setinggs设置,在为django创建表的时候顺带把我的app下的表也给创建;如果我们是通过pycharm为我们创建的app,则默认pycharm就帮我们设置,下面的截图是pycharm帮我们设置的app的样式,如果是我们手动创建app,则这里只需要写app的名称即可,比如“app1”就可以了
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
二、下面我们还得介绍模板继承
首先我们看下我们的base.html的内容
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/css/css2.css"> <style> .hide{ display: none; } </style> {% block css %} {% endblock %} </head> <body> <div id="head"> <h2>乌海市第一中学管理系统</h2> <div> 欢迎{{ username }}登陆|<a href="/app1/logout/">注销</a> </div> </div> <div id="left"> <div> <a id="menu_class" href="/app1/classes/">班级管理</a> <a id="menu_student" href="/app1/student/">学生管理</a> <a id="menu_teacher" href="/app1/teacher/">老师管理</a> </div> </div> <div id="right"> {% block right %} {% endblock %} </div> <script src="/static/jq/jquery-3.3.1.js"></script> {% block jq %} {% endblock %} </body> </html>
首先我们在base.html中至少要写3个block,分别是css、content,还有js的
首先是css的block
<style> .hide{ display: none; } </style> {% block css %} {% endblock %}
然后content的block
<div id="right"> {% block right %} {% endblock %} </div>
最后是js的block
<script src="/static/jq/jquery-3.3.1.js"></script> {% block jq %} {% endblock %}
然后我们写一个class的html,继承base.html
{% extends "base.html" %} {% block css %} <link rel="stylesheet" href="/static/css/css1.css"> <link rel="stylesheet" href="/static/css/css2.css"> <style> form p,table{ margin-left:70px; } .modal{ position: fixed; background-color: coral; width: 400px; height: 400px; z-index: 101; left: 50%; top: 50%; margin-left: -200px; margin-top: -200px; } .shade{ position: fixed; background-color: gray; left: 0; top: 0; right: 0; bottom: 0; z-index: 100; opacity: 0.9; } .del_class_modal{ position: fixed; width: 200px; height: 150px; margin-left: -100px; margin-top: -75px; left: 50%; top: 50%; z-index: 101; background-color: green; } .hide{ display: none; } #page_str a{ padding: 10px; } #active{ color: yellow; font-size: larger; background-color: black; } </style> {% endblock %} {% block right %} <h1>班级页面</h1> <form method="post" action="/app1/classes/"> 班级名称:<input type="text" placeholder="新的班级名称" name="new_class_name"> <span id="error">{{ error }}</span> <p> <input type="submit" value="form添加"> <input type="button" value="ajax添加" id="ajax_add_class"> </p> <hr> </form> <table border="1"> <caption>班级列表</caption> <thead> <tr> <th>班级id</th> <th>班级名称</th> <th>操作</th> </tr> </thead> <tbody> {% for class in class_list %} <tr> <td>{{ class.id }}</td> <td>{{ class.classes_name }}</td> <td> <a href="/app1/edit_class/?classid={{ class.id }}">form编辑班级</a>|<a href="/app1/del_class/?classid={{ class.id }}">form删除班级</a>| <input type="button" value="ajax_编辑" class="ajax_edit_clas">|<input type="button" value="ajax_删除" class="ajax_del_class"> </td> </tr> {% endfor %} </tbody> </table> <div id="page_str"> {{ page_str|safe }} </div> <div class="hide shade" id="ajax_shade"></div> <div class="hide modal" id="ajax_modal"> <form> <label for="class_name">班级名称:</label><input type="text" id="ajax_class_name"> <span id="ajax_error"></span> <br> <input type="button" value="取消" id="del_ajax_add_class"> <input type="button" value="确认" id="confir_add_class"> <input type="reset" value="重置"> </form> </div></div> <div class="hide del_class_modal" id="ajax_del_class_modal"> <span class="hide" id="ajax_del_class_id"></span> 是否删除<span id="ajax_del_class_name"></span> <br> <span style="color:red" id="ajax_del_class_error"></span> <input type="button" value="确定" id="ajax_del_class_botton"> <input type="button" value="取消" id="not_ajax_del_class_botton"> </div> {% endblock %} {% block jq %} <script> $(function () { $("#menu_class").addClass("active"); ajax_add_class(); del_ajax_add_class(); ajax_post_new_class(); ajax_del_class(); not_ajax_del_class(); ajax_del_class_botton(); }) function ajax_add_class() { $("#ajax_add_class").bind("click",function () { $("#ajax_error").html() $("#ajax_modal").removeClass("hide"); $("#ajax_shade").removeClass("hide"); }) } function del_ajax_add_class() { $("#del_ajax_add_class").bind("click",function () { $("#ajax_modal").addClass("hide"); $("#ajax_shade").addClass("hide"); }) } function ajax_post_new_class() { $("#confir_add_class").bind("click",function () { var new_class_name = $("#ajax_class_name").val() $.ajax({ url:"/app1/ajax_post_new_class/", type:"post", data:{ new_class_name:new_class_name }, success:function (data) { var data = JSON.parse(data); console.log(data) if (data["state"] == true){ window.location.href = "/app1/classes/" }else { var error = data["error"]; $("#ajax_error").html(error) } } }) }) } function ajax_del_class() { $(".ajax_del_class").bind("click",function () { var del_class_id = $(this).parent().prev().prev().html(); var del_class_name = $(this).parent().prev().html(); $("#ajax_del_class_id").html(del_class_id); $("#ajax_del_class_name").html(del_class_name); $("#ajax_shade").removeClass("hide"); $("#ajax_del_class_modal").removeClass("hide") }) } function not_ajax_del_class() { $("#not_ajax_del_class_botton").bind("click",function () { $("#ajax_shade").addClass("hide") $("#ajax_del_class_modal").addClass("hide") }) } function ajax_del_class_botton() { $("#ajax_del_class_botton").bind("click",function () { var temp_id = $("#ajax_del_class_id").html() $.ajax( { url:"/app1/ajax_del_class_botton/", type:"post", data:{ "ajax_del_class_id":temp_id }, success:function (data) { data = JSON.parse(data) if (data["state"] == "true"){ window.location.href = "/app1/classes/" }else { var error_info = data["info"] $("#ajax_del_class_error").html(error_info) } } } ) }) } </script> {% endblock %}
{% extends "base.html" %}去继承母版的html
通过下面的方法重写母版中的数据
{% block right%}
{% endblock %}
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
下面我们正常进入class的流程的学习,下面就是我们登陆进class的页面的展示
这里我们用到的知识点很多
1、首先是左边框,如果我们当前是老师页面,则左边的老师的菜单要被选中,这个是通过js实现的,
首先我们在模板中定义了左边菜单的菜单栏,并分别为每个菜单栏设置了一个id的属性
我们在class页面,待页面加载成功后,通过addClass方法自动为这个标签加一个class属性,active属性,这个active的属性就是表示被选中
我们在看这个active的属性是如何定义的,只是定义个background-color的属性
.active{ background-color: purple; }
另外我们还为左边的菜单定义hover的css属性,意思是输入移动上显示的css的样式
#left a:hover{ background-color: green; }
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
下面我们看下面页面上的添加班级按钮是如何实现的,这里我们分别实现了用form表单的方式添加班级和ajax的方式添加班
先看通过form表单的方式添加班级
html的代码
<form method="post" action="/app1/classes/"> 班级名称:<input type="text" placeholder="新的班级名称" name="new_class_name"> <span id="error">{{ error }}</span> <p> <input type="submit" value="form添加"> <input type="button" value="ajax添加" id="ajax_add_class"> </p> <hr> </form>
form的向后端提交数据的方式为:post
form的向后端提交数据的url为:/app1/classes/
input标签中的placeholder就是表框中显示的内容,提示用户这里该输入什么
这里我们没有用到label这个标签,但是我这里的说明一下,因为我们在登陆的页面用到了,但是在上一篇博客中忘记说了
lable标签和input标签配合使用,我们看到label表中有一个for="username"的属性,实现的效果就是点击label标签中的用户名,鼠标的输入框会自动跳转到for指向的username这个id的input框的输入框中
<p><label for="username">用户名</label>:<input type="text" placeholder="用户名" name="user_name" id="username"></p> <p><label for="userpwd">密码</label>:<input type="password" placeholder="密码" name="user_pwd" id="userpwd"></p>
下面我们继续来介绍form表单的方式添加班级的流程
然后到urls中找到form表单要提交数据的url,看下这个url是执行的视图函数,我们看到也是classes这个函数,但是不同的是这次是通过post的方式方式的
下面我们来看下视图函数classes
这里的知识点就非常多了,我们一一道来
a、首先我们为classes这个班级加了一个装饰器,outer,这个装饰器的作用就是判断用户这次的请求【request】的session是否有和我们匹配的用户名和密码,如果没有的话,则直接返回到登录,如果有的话,则执行classes这个函数,下面就是这个outer函数的代码
def outer(func): def inner(request,*args,**kwargs): session_name = request.session.get("username") session_pwd = request.session.get("userpwd") if session_name == "root" and session_pwd == "root": rep = func(request,*args,**kwargs) return rep else: return redirect("/app1/home/") return inner
b、下面我们看下分页这个控件是如何实现,因为我们的班级可能会很多,如果不进行分页,则一个页面显示所有的班级则不显示,所以要实现分页的功能,我们把分页这个功能单放在一个模块中,写了成类的
下面看下具体的page.py的代码,初始化这个page_helpler的类需要以下几个参数
count:一共有多少数据
current_page:要先第几页的数据
per_page_num:一页显示多少条数据
base_url:url地址,因为我们分页在页面的显示是一个一个a标签,这个a表现的href属性指向的地址我们也写自定义的
我们这个控件实现的效果就是,每页显示10条数据,一共仅仅显示11页的数据
我们先来看下我的算法
通过page_count方法中的divmod方式先算出来一共有多少条数据,divmod方法返回一个tuple,这个tuple的第一个值是除数,第二个是余数,如果余数大于0,则总页数是除数+1,如果余数等于0,则总页数就数除数
算法如下
如果总数<=11
则页面的a标签的开始值为1,页面的a标签的结束值为总数
如果总数>11
如果当前的current_page<=6
则页面的a标签的开始值为1,页面的a标签的结束之为11
如果当前的current_page + 5 + 1>总数
则页面的a标签的开始值为总数-10,页面的a标签的结束的值为总数+1
else:
则页面的a标签的开始至为current_page - 5,则页面的a标签的结束值为current + 5 + 1
class page_helper(): def __init__(self,count,current_page,per_page_num,base_url): self.count = count self.current_page = current_page self.per_page_num = per_page_num self.base_url = base_url def page_count(self): before, after = divmod(self.count, self.per_page_num) if after > 0: class_count = before + 1 else: class_count = before return class_count def page_start(self): if self.page_count() <= 11: start_int = 1 end_int = self.page_count() else: if self.current_page <= 6: start_int = 1 end_int = 11 elif self.current_page + 5 + 1 > self.page_count(): start_int = self.page_count() - 10 end_int = self.page_count() + 1 else: start_int = self.current_page - 5 end_int = self.current_page + 5 + 1 return start_int def page_end(self): if self.page_count() <= 11: start_int = 1 end_int = self.page_count() else: if self.current_page <= 6: start_int = 1 end_int = 11 elif self.current_page + 5 + 1 > self.page_count(): start_int = self.page_count() - 10 end_int = self.page_count() + 1 else: start_int = self.current_page - 5 end_int = self.current_page + 5 + 1 return end_int def db_start(self): return (self.current_page - 1) * 10 + 1 def db_end(self): return self.current_page * 10 + 1 def page_list(self): if self.current_page == 1: before_page = """<a href="#">上一页</a>""" else: before_page = """<a href="{url}?p={num}">上一页</a>""".format(url=self.base_url,num=self.current_page - 1) page_list = [] page_list.append(before_page) for i in range(self.page_start(),self.page_end() + 1): if i == self.current_page: s = """<a href="{url}?p={num}" class="active">{num}</a>""".format(url=self.base_url,num=i) else: s = """<a href="{url}?p={num}">{num}</a>""".format(url=self.base_url,num=i) page_list.append(s) if self.current_page == self.page_count(): after_page = """<a href="#">下一页</a>""" else: after_page = """<a href="{url}?p={num}">下一页</a>""".format(url=self.base_url,num=self.current_page + 1) page_list.append(after_page) page_str = "".join(page_list) return page_str
page_count:计算总的页数
page_start:计算a标签的开始值
page_end:计算a标签的结束的值
db_start:计算页面显示的数据的开始的数据
db_end:计算页面显示的数据的结束的数据
page_list:计算后端返回给前端的字符串,这段字符串就会被前端渲染成具体的a标签,供客户操作
这里还有一个知识点
这里如果后端返回一段html代码的字符串,则前端不会把这段字符串渲染为html代码,而仅仅是渲染为普通的字符串
我们这里有2种方法
方法1;前端去处理,用管道付加一个safe方法,告诉html页面,我这段代码是安全的,你可以为我渲染
后端就可以直接放回一个字符串就可以了
方法2:在后端处理,先需要导入一个模块的make_safe方法
用make_safe来处理返回的字符串,则前端就可以直接接受这个字符串了,页面可以正常渲染这个html变量
下面我具体来看下添加的函数,这里有以下几个知识点
a、判断数据的合法性,首先判断名称是否为空,然后判断是否重名,通过exists()方法来判断名称是否已经存在
b、如果校验通过,则往单表中写数据,用create()方法为单表添加数据
c、就是locals()方法,这个方位就是这个函数所有的局部变量放在一个dict中,用作render方法的渲染
下面是所有的代码,慢慢看
@outer def classes(request): from django.utils.safestring import mark_safe method = request.method.lower() if method == "get": count = models.classes.objects.all().count() current_page = int(request.GET.get("p",1)) base_url = request.path obj = page.page_helper(count,current_page,10,base_url) class_list = models.classes.objects.all()[obj.db_start()-1:obj.db_end()-1] error = "" return render(request,"classes.html",{"class_list":class_list,"error":error,"page_str":obj.page_list}) else: new_class_name = request.POST.get("new_class_name",None) if not new_class_name: error = "班级名称不允许为空" elif models.classes.objects.filter(classes_name=new_class_name).exists(): error = "班级名称[{name}]已经存在,请输入新的名称".format(name=new_class_name) else: models.classes.objects.create( classes_name = new_class_name ) # class_list = models.classes.objects.all() return render(request,"classes.html",locals())
至此,form表单的方式添加班级已经完成
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
这里开始介绍ajax的方式添加班级
先看下前端的代码
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
标签::hover IV com ict teacher yellow src 建表 方法
原文地址:https://www.cnblogs.com/bainianminguo/p/9190236.html