3.模板
MVT中的T,template
3.0扩展
问:模板渲染的过程是在服务器端完成的,还是在客户端完成的?
答:服务器。
过程:
客户端访问/use_template/,服务器调用对应的视图函数,进行模板的渲染,给模板文件传递变量,将模板文件中的变量进行替换,获取替换之后的html内容,将替换之后的html内容返回给客户端,返回渲染之后的完整的html页面,客户端只是显示。
web网站开发的两种模式:
1)前后端不分离:前端看到的效果是由后端进行控制的。
2)前后端分离:后端只返回前端所需的数据,至于数据怎么展示,由前端自己控制。
3.1模板的作用
渲染产生html页面内容,进行数据展示
3.2模板的使用
flask中:
render_template('模板文件名',<key>=<value>,.....)
Django中:
1、设置模板目录
在工程中创建模板目录templates。在settings.py配置文件中修改TEMPLATES配置项的DIRS值:
'DIRS': [os.path.join(BASE_DIR, 'templates')], # 此处修改
2、render(request,'模板文件名',<字典>)
render返回的是一个响应的对象。
render 其实就是就是下面模板的详细步骤的一个简写封装。
3.3模板的详细步骤(重点掌握)
如果我们不想返回响应对象,只是想渲染一下页面,替换数据,那么我们可以按下面的来。
我们使用模板的详细步骤:
1、加载模板:指定使用模板文件,获取模板对象
from django.template import loader
temp = loader.get_template('模板文件名')
2、模板渲染:给模板文件传递变量,将模板文件中的变量进行替换,获取替换之后的html内容
res_html = temp.render(字典)
3、创建响应对象
return HttpResponse(res_html)
3.4模板语法(了解)
3.4.1模板变量
变量名必须由字母、数字、下划线(不能以下划线开头)和点组成。
语法如下:{{变量}}
模板变量可以使python的内建类型,也可以是对象。
代码语言:javascript复制def index(request):
context = {
'city': '北京',
'adict': {
'name': '西游记',
'author': '吴承恩'
},
'alist': [1, 2, 3, 4, 5]
}
return render(request, 'index.html', context)
代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>{{ city }}</h1>
<h1>{{ adict }}</h1>
<h1>{{ adict.name }}</h1> 注意字典的取值方法
<h1>{{ alist }}</h1>
<h1>{{ alist.0 }}</h1> 注意列表的取值方法
</body>
</html>
django中的模板变量不能进行运算。
3.4.2模板语句
1)for循环:
代码语言:javascript复制{% for item in 列表 %}
循环逻辑
{{forloop.counter}}表示当前是第几次循环,从1开始
{%empty%} 列表为空或不存在时执行此逻辑
{% endfor %}
2)if条件:
代码语言:javascript复制{% if ... %}
逻辑1
{% elif ... %}
逻辑2
{% else %}
逻辑3
{% endif %}
3)比较运算符如下:
代码语言:javascript复制==
!=
<
>
<=
>=
4)布尔运算符如下:
代码语言:javascript复制and
or
not
注意:运算符左右两侧不能紧挨变量或常量,必须有空格。
代码语言:javascript复制{% if a == 1 %} # 正确
{% if a==1 %} # 错误
3.4.3过滤器
语法如下:
使用管道符号|来应用过滤器,用于进行计算、转换操作,可以使用在变量、标签中。
如果过滤器需要参数,则使用冒号:传递参数。
代码语言:javascript复制变量|过滤器:参数
列举几个如下:
safe,禁用转义,告诉模板这个变量是安全的,可以解释执行
length,长度,返回字符串包含字符的个数,或列表、元组、字典的元素个数。
default,默认值,如果变量不存在时则返回默认值。
代码语言:javascript复制data|default:'默认值'
date,日期,用于对日期类型的值进行字符串格式化,常用的格式化字符如下:
- Y表示年,格式为4位,y表示两位的年。
- m表示月,格式为01,02,12等。
- d表示日, 格式为01,02等。
- j表示日,格式为1,2等。
- H表示时,24进制,h表示12进制的时。
- i表示分,为0-59。
- s表示秒,为0-59。
value|date:"Y年m月j日 H时i分s秒"
3.4.4注释
1)单行注释语法如下:
代码语言:javascript复制{#...#}
2)多行注释使用comment标签,语法如下:
代码语言:javascript复制{% comment %}
...
{% endcomment %}
3.4.5模板继承
模板继承和类的继承含义是一样的,主要是为了提高代码重用,减轻开发人员的工作量。
父模板
如果发现在多个模板中某些内容相同,那就应该把这段内容定义到父模板中。
标签block:用于在父模板中预留区域,留给子模板填充差异性的内容,名字不能相同。 为了更好的可读性,建议给endblock标签写上名字,这个名字与对应的block名字相同。父模板中也可以使用上下文中传递过来的数据。
代码语言:javascript复制{% block 名称 %}
预留区域,可以编写默认内容,也可以没有默认内容
{% endblock 名称 %}
子模板
标签extends:继承,写在子模板文件的第一行。
代码语言:javascript复制{% extends "父模板路径"%}
子模版不用填充父模版中的所有预留区域,如果子模版没有填充,则使用父模版定义的默认值。
填充父模板中指定名称的预留区域。
代码语言:javascript复制{% block 名称 %}
实际填充内容
{{ block.super }}用于获取父模板中block的内容
{% endblock 名称 %}
3.4.6Django和Flask模板的区别
1、模板变量
a)Django使用模板变量的时候,无论是字典、列表或元组的元素,都需要使用.
不能使用[]
,字典是.key
,元组和列表是.index
下标;这是和flask有区别的地方。
b)Django中的模板变量不能直接进行算术运算
2、模板控制语句:条件判断和for循环
a)条件判断:Django模板中在进行条件判断时候,比较操作符两边必须有空格
b)for循环:Django模板中的for循环和jinja2模板中for循环对比。
代码语言:javascript复制# jinja2模板中for循环
{% for ... in ... %}
# 遍历不为空时的逻辑
# 获取for循环遍历到了第几次
{{ loop.index }}
{% else %}
# 遍历为空时的逻辑
{% endfor %}
# Django模板中for循环
{% for ... in ... %}
# 遍历不为空时的数据
# 获取for循环遍历到了第几次
{{ forloop.couter }}
{% empty %}
# 遍历为空时的逻辑
{% endfor %}
3、模板过滤器
a) jinja2模板过滤器使用:
{{ 模板变量 | 过滤器(参数...)}}
b) Django中模板过滤器的使用:
{{ 模板变量 | 过滤器:参数 }}
注意:Django中过滤器:
号之后只能接收一个参数
4.数据库
ORM框架:
作用:将模型类和数据表进行对应,通过面向对象的方式进行数据库的操作。
flask中SQLALchemy
Django中自带ORM框架,可以直接进行使用。
4.1数据库链接配置
flask中:
SQLALCHEMY_DATABASE_URI = 'mysql://<username>:<password>@<host_ip>:<port>/<db>'
Django中:
1、pip install pymysql
2、setting里面的DATABASES里面进行数据库配置
3、首次启动时需要在项目同名的目录下__init__.py
里面添加两句话
import pymysql
导入
pymysql.install_as_MySQLdb()
调用方法
sqlite是小型的数据库,用在手机里,默认的是它。我们可以根据我们的需求改为mysql。
4.2定义模型类
1)flask定义模型类:
代码语言:javascript复制db = SQLAlchemy(app)
class User(db.Model):
"""模型类"""
# 字段名 = db.Column(字段类型,选项参数)
# ....
__tablename__ = "<表名>"
2)Django中定义模型类
代码语言:javascript复制class 模型类名(models.Model):
# 字段名 = models.字段类型(选项参数)
# ...
class Meta:
db_table = "<表名>"
数据删除的时候,有一种逻辑删除:就是不是真正的删除,而是做一个删除的标记,比如说加一个字段,0表示删除,1表示没删除,然后展示的时候根据标记展示,也达到了删除的目的。
Django中的id不需要定义,默认为我们添加了id,是主键,并且自增长。id可以使用pk代替(primary key)
定义字段名的时候,不允许使用连续的下划线。
字段类型
类型 | 说明 |
---|---|
AutoField | 自动增长的IntegerField,通常不用指定,不指定时Django会自动创建属性名为id的自动增长属性 |
BooleanField | 布尔字段,值为True或False |
NullBooleanField | 支持Null、True、False三种值 |
CharField | 字符串,参数max_length表示最大字符个数 |
TextField | 大文本字段,一般超过4000个字符时使用 |
IntegerField | 整数 |
DecimalField | 十进制浮点数, 参数max_digits表示总位数, 参数decimal_places表示小数位数,和下面的区别是精度不同。保存金钱的时候选这个。 |
FloatField | 浮点数 |
DateField | 日期, 参数auto_now表示每次保存对象时,自动设置该字段为当前时间,用于"最后一次修改"的时间戳,它总是使用当前日期,默认为False; 参数auto_now_add表示当对象第一次被创建时自动设置当前时间,用于创建的时间戳,它总是使用当前日期,默认为False; 参数auto_now_add和auto_now是相互排斥的,组合将会发生错误 |
TimeField | 时间,参数同DateField |
DateTimeField | 日期时间,参数同DateField |
FileField | 上传文件字段 |
ImageField | 继承于FileField,对上传的内容进行校验,确保是有效的图片 |
选项
选项 | 说明 |
---|---|
null | 如果为True,表示允许为空,默认值是False |
db_column | 字段的名称,如果未指定,则使用属性的名称。字段的名称可以我们自己指定。 |
db_index | 若值为True, 则在表中会为此字段创建索引,默认值是False |
default | 默认 |
primary_key | 若为True,则该字段会成为模型的主键字段,默认值是False,一般作为AutoField的选项使用 |
unique | 如果为True, 这个字段在表中必须有唯一值,默认值是False |
外键
在设置外键时,需要通过on_delete选项指明主表删除数据时,对于外键引用表数据如何处理,在django.db.models中包含了可选常量:
CASCADE 级联,删除主表数据时连通一起删除外键表中数据
PROTECT 保护,通过抛出ProtectedError异常,来阻止删除主表中被外键应用的数据
SET_NULL 设置为NULL,仅在该字段null=True允许为null时可用
4.3迁移生成数据表
flask中:
安装扩展flask-migrate
python manage.py db init
生成迁移文件夹
python manage.py db migrate
生成迁移文件
python manage.py db upgrade
迁移
Django中:
不需要创建文件夹
1、生成迁移文件
python manage.py makemigrations
2、迁移生成表
python manage.py migrate
mysql数据库中:
desc 表名;
查看表结构
在我们迁移的时候,Django的子应用会默认为我们创建一些表,
4.4演示工具使用
4.4.1shell工具
Django的manage工具提供了shell命令,帮助我们配置好当前工程的运行环境(如连接好数据库等),以便可以直接在终端中执行测试python语句。
通过如下命令进入shell
python manage.py shell
然后导入我们的模型类
from booktest.models import BookInfo, HeroInfo
4.4.2查看MySQL数据库日志
查看mysql数据库日志可以查看对数据库的操作记录。 mysql日志文件默认没有产生,需要做如下配置:
sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf
把68,69行前面的#去除,然后保存并使用如下命令重启mysql服务。
sudo service mysql restart
使用如下命令打开mysql日志文件。
代码语言:javascript复制tail -f /var/log/mysql/mysql.log # 可以实时查看数据库的日志内容
# 如提示需要sudo权限,执行
# sudo tail -f /var/log/mysql/mysql.log
4.5通过模型类和对象进行数据操作(增删改查)
4.5.1新增
1、创建模型类对象,对象.save()
注意:添加HeroInfo时,可以给hbook赋值,也可以直接表中hbook_id赋值
代码语言:javascript复制>>> from datetime import date
>>> book = BookInfo(
btitle='西游记',
bpub_date=date(1988,1,1),
bread=10,
bcomment=10
)
>>> book.save()
>>> hero = HeroInfo(
hname='孙悟空',
hgender=0,
hbook=book
)
>>> hero.save()
>>> hero2 = HeroInfo(
hname='猪八戒',
hgender=0,
hbook_id=book.id
)
>>> hero2.save()
2、模型类.objects.create(...)
代码语言:javascript复制>>> HeroInfo.objects.create(
hname='沙悟净',
hgender=0,
hbook=book
)
<HeroInfo: 沙悟净>
4.5.2修改
1、 查询对象->修改对象属性->对象.save()
修改模型类对象的属性,然后执行save()方法
代码语言:javascript复制hero = HeroInfo.objects.get(hname='猪八戒')
hero.hname = '猪悟能'
hero.save()
2、 模型类.objects.filter(...).update(...)
使用模型类.objects.filter().update(),会返回受影响的行数
代码语言:javascript复制HeroInfo.objects.filter(hname='沙悟净').update(hname='沙僧')
4.5.3删除
1、查询对象->对象.delete()
模型类对象delete
代码语言:javascript复制hero = HeroInfo.objects.get(id=13)
hero.delete()
2、模型类.objects.filter(...).delete()
模型类.objects.filter().delete()
代码语言:javascript复制HeroInfo.objects.filter(id=14).delete()
优质文章推荐:
公众号使用指南
redis操作命令总结
前端中那些让你头疼的英文单词
Flask框架重点知识总结回顾
项目重点知识点详解
难点理解&面试题问答
flask框架中的一些常见问题
团队开发注意事项
浅谈密码加密