day63 django-模板语言
我们的功能是需要解耦的,从开始就一直在强调这一点,所以我们的函数需要另外放到一个单独的文件里面,一般都是放到views文件里面,views叫做视图,一般术语叫做视图函数,用来进行各种逻辑判断的,需要一个功能的时候就去写一段逻辑代码块,都是存放到这里的,所谓的视图就是既视感,我们写到这里的都是可以执行然后看到功能的效果的,而功能和需求是随时会变动的,所以这里的函数都是根据需求随时满足的,
而我们的tool文件夹则不一样,首先声明一下我们的tool文件夹[tool这个名字是自定义的,没有规律按照个人洗好即可,你要能够分辨出来它是干什么的就行]是python-package格式的,它创建好之后会有一个自带的init文件,里面是空的,我们自己在里面新建py文件就好,我们的封装好的函数都是放在那里面的,所谓的封装好的就是类似于模块一样的,那些功能是会被反复的调用的,所以我们为了节省代码,所以就把他们都单独拎出来了,写成函数,用的时候引用就好了.
我们来整理一下我们的django的一些语法,专用术语叫做模板语言:
我们都学了这几个模板语言:
在django的模板语言里面设置变量,用with标签:{%with%} {%endwith%},如下所示,我下面设置的变量是字符串。
{% with morning_opt="01" %} {% endwith %}
{# 这是注释 #}
{{这是放变量名}}
还有循环,我们的这个循环就类似于我们的for循环,不过他是有开始和结束的
{% for i in p%}
{{forloop.counter}} # 这里我们是要对循环的元素进行排序,
{{forloop.last}}
{{forloop.first}}
默认是从1开始的这样写就是从0开始了{{forloop.counter0}}
{{ i }} # 这里的i如果是字典的话,我们的语法是支持使用{{i.name}}
{% endfor %}
还有if判断:
{%if student.cid == class.id%}
<option selected value="{{ class.id }}">{{ class.cname }}</option>
{%else%}
<option value="{{ class.id }}">{{ class.cname }}</option>
{%endif%}
我们使用django的时候需要连接数据库,在连接库的时候,我们需要传一些参数,然后这些参数,我们每次写函数的时候都会重复的去写它,这样的话反复去连接数据库的过程本身就是有极大的优化空间的,鉴于此,我们使用了面向对象编程,
下面是代码:
import pymysql DB_CONFIG = { "host": "localhost", "user": "root", "password": "123", "database": "book_list", "charset": "utf8" } # 指定单条语句 def update(sql, arg=None): # 取数据库里面学生表插入一条数据 conn = pymysql.connect( host=DB_CONFIG["host"], user=DB_CONFIG['user'], password=DB_CONFIG['password'], database=DB_CONFIG['database'], charset=DB_CONFIG['charset'], ) # 指定输出的结果类型是字典 cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) cursor.execute(sql, arg) conn.commit() cursor.close() conn.close() # 查询单个数据记录 def get_one(sql, arg=None): conn = pymysql.connect( host=DB_CONFIG["host"], user=DB_CONFIG["user"], password=DB_CONFIG["password"], database=DB_CONFIG["database"], charset=DB_CONFIG["charset"] ) # 指定输出的结果是类型是字典 cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) cursor.execute(sql, arg) ret = cursor.fetchone() cursor.close() conn.close() return ret # 查询多条数据 def get_list(sql, arg=None): conn = pymysql.connect( host=DB_CONFIG["host"], user=DB_CONFIG["user"], password=DB_CONFIG["password"], database=DB_CONFIG["database"], charset=DB_CONFIG["charset"] ) cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) cursor.execute(sql) ret = cursor.fetchall() cursor.close() conn.close() return ret def magic(data_o): tmp = {} for i in data_o: if i["id"] not in tmp: tmp[i["id"]] = {"id": i["id"], "tname": i["tname"], "cname": [i["cname"]],} else: # 我们的这个else是要跟上面的if平级的,不能够写到for那一级,否则得到的结果会出问题, # 它就显示的都是单个的字母,而不是完整的单词 tmp[i["id"]]["cname"].append(i["cname"]) data = list(tmp.values()) return data def create(sql, arg=None): conn = pymysql.connect( host=DB_CONFIG["host"], user=DB_CONFIG["user"], password=DB_CONFIG["password"], database=DB_CONFIG["database"], charset=DB_CONFIG["charset"] ) cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) cursor.execute(sql, arg) the_id = cursor.lastrowid # 这里的lastrowid是得到最后一个数据, 提交之后,获取刚插入的数据的ID conn.commit() cursor.close() conn.close() return the_id # 批量执行单挑语句 def pl_modify(sql, arg=None): conn = pymysql.connect( host=DB_CONFIG["host"], user=DB_CONFIG["user"], password=DB_CONFIG["password"], database=DB_CONFIG["database"], charset=DB_CONFIG["charset"] ) cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) cursor.executemany(sql, arg) # 这里我们需要执行多条操作,使用executemany来完成 conn.commit() cursor.close() conn.close() # 接下来我们使用比较高级一点的用法,面向对象去把相同的代码封装到一个类里面, # 然后把不同的方法作为类里面的函数去使用,可以节省代码 class DBHelper(): def __init__(self): self.conn = None self.cursor = None self.connect() def connect(self): self.conn = pymysql.connect( host=DB_CONFIG["host"], user=DB_CONFIG["user"], password=DB_CONFIG["password"], database=DB_CONFIG["database"], charset=DB_CONFIG["charset"] ) self.cursor = self.conn.cursor(cursor=pymysql.cursors.DictCursor) # 指定单条语句 def update(self, sql, arg=None): # 取到数据库里面的学生表插入一条新数据 # 指定输出的结果类型是字典 self.cursor.execute(sql, arg) self.conn.commit() # 批量执行单条语句 def pl_modify(self, sql, arg=None): self.cursor.executemany(sql, arg) self.conn.commit() # 执行单条语句,同时获取最后插入的那条数据 def create(self, sql, arg=None): self.cursor.execute(sql, arg) the_id = self.cursor.lastrowid self.conn.commit() return the_id # 查询单个数据 def get_one(self, sql, arg=None): self.cursor.execute(sql, arg) ret = self.cursor.fetchone() return ret # 查询多个数据 def get_list(self, sql, arg=None): self.cursor.execute(sql, arg) ret = self.cursor.fetchall() return ret def close(self): self.cursor.close() self.conn.close() # 进入with语句自动执行,自动进入自动退出,我们使用with语法打开一个文件的时候是不需要另外关闭文件的,它本身自带关闭功能 # with 就是一个类,它底层就是一个类,我们使用with的时候用它本身就可以实例化出来一个对象,我们使用with语法的时候, # as后面的就是我们的实例化的对象,这个对象是可以自定义的,我们首先是需要在这里定义enter和exit使用方法,才能使用with方法, # 否则就需要使用传统方法,在下面使用类来实例化一个对象 def __enter__(self): return self def __exit__(self, exc_type, exc_val, exc_tb): self.close() # db = DBHelper()
如下是我们的例子:我们把上面的类和类里面封装的函数方法都使用到了,
# 展示所有的班级列表 def class_form(request): # 这个函数是展示所有的班级列表 # 1.去数据库里面取出数据 # conn = pymysql.connect( # host="localhost", # user="root", # password="123", # database="book_list", # charset="utf8") # 指定输出的结果类型是字典这里的DictCursor是django里面自带的封装好的功能, # 我们把它记下来然后用的时候想到它就可以完成我们需要的工作 # cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) # cursor=conn.cursor() # 这样写就是得到元祖的结果, # 我们需要把它转换成字典,然后我们才能通过字典的特性键对值的方式去取值 sql = "select id,cname from class order by id;" # cursor.execute(sql) # ret = cursor.fetchall() with db_master.DBHelper() as qw: ret = qw.get_list(sql) # cursor.close() # conn.close() print(ret) # 2 用数据去填充HTML页面 这里需要去看视频理解一下---->已经理解过了 # 这里是key和value的方式,{key:value},class_form是变量名, # 我们这里写的变量名class_form需要和HTML里面的for i in class_form对应上, # 这两个是必须要保持一致的,后面的ret是我们上面mysql语句运行之后的得到的结果赋值给这个变量了 return render(request, 'class-form.html', {"class_form": ret}) # , {"class-form": ret}这里的变量命名不够规范所以会报错 # 添加班级 def add_class(request): if request.method == "POST": class_name = request.POST.get("cname") # 因为我们的id是自增的所以我们在这里只需要增加cname就好了,只需要定义这一个变量就够了 # 1.去数据库里面取出数据 # 指定输出的结果类型是字典这里的DictCursor是django里面自带的封装好的功能, # 我们把它记下来然后用的时候想到它就可以完成我们需要的工作 sql = "insert into class (cname) VALUES (%s);" with db_master.DBHelper() as ff: ff.update(sql, [class_name]) return redirect("/class_form/") return render(request, 'add-class.html') # 删除课程 def delete_class(request): # 根据班级id删除 # 班级id从数据库里面取出来 print(request.GET) class_id = request.GET.get("class_id") print(class_id) # 去到数据库里面删除 sql = "delete from class where id=%s;" # 对数据库进行改变需要提交操作 with db_master.DBHelper() as obj: obj.update(sql,[class_id]) # return HttpResponse(class_id) return redirect('/class_form/') # 修改课程 def edit_class(request): if request.method == "POST": class_id = request.POST.get("id") class_name = request.POST.get("cname") # 去数据库里面更新 sql = "update class set cname=%s where id=%s;" with db_master.DBHelper() as fh: fh.update(sql, [class_name, class_id]) return redirect('/class_form/') # 取到被编辑的班级id class_id = request.GET.get("class_id") # 去数据库里面查询当前班级的信息 sql = "select id,cname from class where id=%s;" ret = db_master.get_one(sql, [class_id]) print(ret) return render(request, "edit-class.html", {"class_info": ret})