Django模板层知识
目录
一.过滤器
1.什么是过滤器
2.语法
3.统计字符串长度
4.默认值
5.文件大小
6.日期格式化
原始格式
格式化输出
7.切片操作
8.切取摘要
字符
9.移除指定字符
10.拼接字符
11.加法
12.取消转义
前端转义
后端转义
二.标签
1.forloop
2.if 语句
3.混用forloop+if
三.模型层
1.数据准备
(1)测试脚本
(2)数据
2.单表的操作
(1)数据的增加
(2)数据的删除
(3)数据的更改
3.查看SQL语句的方式
(1)方式一
(2)方式二
4.双下划线查询
一.过滤器
1.什么是过滤器
过滤器就类似于模板语法内置的内置方法
Django内置有60多个过滤器
2.语法
{{ 数据|过滤器:参数 }}
3.统计字符串长度
{{ c|length }}
def length(value):"""Returns the length of the value - useful for lists."""try:return len(value)except (ValueError, TypeError):return 0
4.默认值
<p>默认值{{ f|default:"这是默认值" }}</p>
- 类似于get方法
- 第一个参数如果是True,就会展示第一个值
- 如果第一个参数取不到,就会展示第二个值
def default_if_none(value, arg):"""If value is None, use given default."""if value is None:return argreturn value
5.文件大小
<p>文件大小 {{ file|filesizeformat }}</p>
def filesizeformat(bytes_):"""Formats the value like a 'human-readable' file size (i.e. 13 KB, 4.1 MB,102 bytes, etc.)."""try:bytes_ = float(bytes_)except (TypeError, ValueError, UnicodeDecodeError):value = ungettext("%(size)d byte", "%(size)d bytes", 0) % {'size': 0}return avoid_wrapping(value)def filesize_number_format(value):return formats.number_format(round(value, 1), 1)KB = 1 << 10MB = 1 << 20GB = 1 << 30TB = 1 << 40PB = 1 << 50negative = bytes_ < 0if negative:bytes_ = -bytes_ # Allow formatting of negative numbers.if bytes_ < KB:value = ungettext("%(size)d byte", "%(size)d bytes", bytes_) % {'size': bytes_}elif bytes_ < MB:value = ugettext("%s KB") % filesize_number_format(bytes_ / KB)elif bytes_ < GB:value = ugettext("%s MB") % filesize_number_format(bytes_ / MB)elif bytes_ < TB:value = ugettext("%s GB") % filesize_number_format(bytes_ / GB)elif bytes_ < PB:value = ugettext("%s TB") % filesize_number_format(bytes_ / TB)else:value = ugettext("%s PB") % filesize_number_format(bytes_ / PB)if negative:value = "-%s" % valuereturn avoid_wrapping(value)
6.日期格式化
原始格式
current_time = datetime.datetime.now()<p>日期格式化 {{ current_time }}</p>日期格式化 July 12, 2023, 3:57 p.m.
格式化输出
<p>日期格式化 {{ current_time|date:'Y-m-d H:m:s' }}</p>日期格式化 2023-07-12 15:07:45
7.切片操作
支持步长切片
c = "这是一个示例"<p>切片操作 {{ c|slice:'0:4:2' }}</p>切片操作 这一
8.切取摘要
- 可以指定切取长度
- 按照空格切分
字符
不会将 . 算进切取个数
# 切取单词
sentence = 'I just need someone who will never abandon me'<p>切取单词 {{ sentence|truncatewords:9 }}</p>切取单词 I just need someone who will never abandon me
9.移除指定字符
sentence = 'I just need someone who will never abandon me'<p>移除指定字符,例空格 {{ sentence|cut:" " }}</p>移除指定字符,例空格 Ijustneedsomeonewhowillneverabandonme
10.拼接字符
d = ["你好", "我好", "大家好"]<p>拼接字符 {{ d|join:"$" }}</p>拼接字符 你好$我好$大家好
11.加法
a = 123<p>拼接字符(加法) {{ a|add:10 }}</p>拼接字符(加法) 133
def add(value, arg):"""Adds the arg to the value."""try:return int(value) + int(arg)except (ValueError, TypeError):try:return value + argexcept Exception:return ''
12.取消转义
以后在写全栈项目时,前端代码不一定必须在前端页面书写,也可以选择先在后端写好再传递给前端页面展示
前端转义
msg = '<h1>斋藤</h1>'<p>转义字符(不转义) {{ msg }}</p><p>转义字符(转义) {{ msg|safe }}</p>转义字符(不转义) <h1>斋藤</h1>转义字符(转义)斋藤(已变成h1标题格式)
后端转义
from django.utils.safestring import mark_safe
res = mark_safe('<h1>飞鸟</h1>')<p>转义字符(转义) {{ res }}</p>转义字符(转义)飞鸟(已变成h1标题格式)
二.标签
1.forloop
d = ["你好", "我好", "大家好"]{% for re in d %}<p>{{ forloop }}</p>{% endfor %}标签
{'parentloop': {}, 'counter0': 0, 'counter': 1, 'revcounter': 3, 'revcounter0': 2, 'first': True, 'last': False}{'parentloop': {}, 'counter0': 1, 'counter': 2, 'revcounter': 2, 'revcounter0': 1, 'first': False, 'last': False}{'parentloop': {}, 'counter0': 2, 'counter': 3, 'revcounter': 1, 'revcounter0': 0, 'first': False, 'last': True}
- first
- 标识for循环是否是第一次
- last
- 标识for循环是否是最后一次
- counter0
- 类似索引
- counter
- 计数
- 取值
d = ["你好", "我好", "大家好"]{% for re in d %}<p>{{ re }}</p>{% endfor %}你好我好大家好
2.if 语句
f = True{% if f %}<p>你好</p>
{% else %}<p>我好</p>
{% endif %}你好
3.混用forloop+if
d = ["你好", "我好", "大家好"]{% for re in d %}{% if forloop.first %}<p>第一次循环</p>{% elif forloop.last %}<p>最后一次循环</p>{% else %}<p>{{ re }}</p>{% endif %}
{% empty %}<p>for循环的对象是空,不支持for循环</p>{% endfor %}第一次循环我好最后一次循环
三.模型层
1.数据准备
(1)测试脚本
-
测试脚本
- 当我们只想要测试Django中的某一个py文件的内容时,我们可以不需要书写前后端交互的形式,而是直接写一个测试脚本即可
-
测试环境的准备
- 在测试文件中书写下面内容
-
这内容其实就是最外部 manage.py 文件中的上面几句话
- 脚本代码无论是写在应用下的 tests.py文件还是自己新建文件,将内容写在新文件中,都会生效
from django.test import TestCase# Create your tests here.
import osif __name__ == "__main__":os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day07.settings")import djangodjango.setup()# 在下面书写我们需要测试的代码# 即所有的测试代码都必须等待环境准备完毕之后才能书写
(2)数据
在models里面创建我们需要的数据库中的表
from django.db import models# Create your models here.class User(models.Model):name = models.CharField(verbose_name="姓名", help_text="姓名", max_length=32)age = models.IntegerField(verbose_name="年龄", help_text="年龄")register_time = models.DateTimeField(verbose_name="注册时间", help_text="注册时间")'''DateFieldDateTimeField两个关键参数auto_now : 每次操作数据的时候该字段会自动将当前时间更新auto_now_add : 在创建数据的时候会自动将当前创建时间记录下来,只要不是人为修改,就不会发生更改'''
配置数据库文件(settings.py)
DATABASES = {'default': {'ENGINE': 'django.db.backends.mysql',# 数据库名字'NAME': 'django_day10',# 用户"USER": "root",# 密码"PASSWORD": "1314521",# IP"HOST": "127.0.0.1",# 端口"PORT": 3306,# 编码集"CHARSET": "utf8",}
}
在项目下的init.py中声明数据库类型
import pymysqlpymysql.install_as_MySQLdb()
2.单表的操作
create
update
delete
all
first
filter
(1)数据的增加
from django.test import TestCase# Create your tests here.
import osif __name__ == "__main__":os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day07.settings")import djangodjango.setup()# 在下面书写我们需要测试的代码# 即所有的测试代码都必须等待环境准备完毕之后才能书写from app01 import models# (1)增加数据# register_time (1)支持自己指定传值res = models.User.objects.create(name="dream", age=18, register_time='2023-06-09')# 返回值为对象本身print(res) # User object# register_time (2)支持传入日期对象import datetime# 生成一个当前的时间对象c_time = datetime.datetime.now()user_obj = models.User.objects.create(name="chimeng", age=18, register_time=c_time)# 保存数据user_obj.save()
(2)数据的删除
# 【2】删除数据
# pk : 自动查找到当前表的主键字段,指代的就是当前表的主键字段
# 使用 pk 后不需要知道当前表的主键字段 , 他会自动帮我们查找并匹配
# (1)方式一
res = models.User.objects.filter(pk=4).delete()
print(res) # (1, {'app01.User': 1})
# (2)方式二
# 拿到当前用户对象
user_obj = models.User.objects.filter(pk=1).first()
# 利用对象的方法进行删除
user_obj.delete()
(3)数据的更改
# 【3】数据的更改
# (1)方式一
res = models.User.objects.filter(pk=5).update(name="mengmeng")
print(res) # 1
# (2)方式二
# 返回的就是当前的数据对象
# 不推荐使用 : 如果查询的数据不存在会直接报错 ,fileter不会
user_onj = models.User.objects.get(pk=5)
# 调用对象更改数据
user_onj.name = "xiaomeng"
user_onj.save()
3.查看SQL语句的方式
(1)方式一
只有queryset对象才能使用该方法
res_list = models.User.objects.values_list('name', 'age')# 返回的数据格式为列表套元祖 - 本质上是一个 QuerySet 对象 ,而不是真的列表print(res_list) # <QuerySet [('xiaomeng', 18)]># 该语句可以查看当前执行命令的 SQL 语句 - 只有queryset对象才能使用该方法print(res_list.query) # SELECT `app01_user`.`name`, `app01_user`.`age` FROM `app01_user`
其他方法:
from django.test import TestCase# Create your tests here.
import osif __name__ == "__main__":os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day07.settings")import djangodjango.setup()# 在下面书写我们需要测试的代码# 即所有的测试代码都必须等待环境准备完毕之后才能书写from app01 import models# # 【1】增加数据# # register_time (1)支持自己指定传值# res = models.User.objects.create(name="dream", age=18, register_time='2023-06-09')# # 返回值为对象本身# print(res) # User object# # register_time (2)支持传入日期对象## import datetime## # 生成一个当前的时间对象# c_time = datetime.datetime.now()# user_obj = models.User.objects.create(name="chimeng", age=18, register_time=c_time)# # 保存数据# user_obj.save()# # 【2】删除数据# # pk : 自动查找到当前表的主键字段,指代的就是当前表的主键字段# # 使用 pk 后不需要知道当前表的主键字段 , 他会自动帮我们查找并匹配# # (1)方式一# res = models.User.objects.filter(pk=4).delete()# print(res) # (1, {'app01.User': 1})# # (2)方式二# # 拿到当前用户对象# user_obj = models.User.objects.filter(pk=1).first()# # 利用对象的方法进行删除# user_obj.delete()## # 【3】数据的更改# # (1)方式一# res = models.User.objects.filter(pk=5).update(name="mengmeng")# print(res) # 1# # (2)方式二# # 返回的就是当前的数据对象# # 不推荐使用 : 如果查询的数据不存在会直接报错 ,fileter不会# user_onj = models.User.objects.get(pk=5)# # 调用对象更改数据# user_onj.name = "xiaomeng"# user_onj.save()###############必知必会十三条################## (1) all() - 查询所有数据# (2) filter() - 带有过滤条件的查询# (3) get() - 根据条件拿数据对象,但是条件不存在会直接抛出异常# (4) first() - 拿queryset中的第一个元素# (5) last() - 拿queryset中的最后一个元素# (6) values() - 可以指定获取的数据字段res = models.User.objects.values('name')# 返回的数据格式为列表套字典 - 本质上是一个 QuerySet 对象 ,而不是真的列表print(res) # <QuerySet [{'name': 'xiaomeng'}]># (7) values_list() - 可以指定获取的数据字段res_list = models.User.objects.values_list('name', 'age')# 返回的数据格式为列表套元祖 - 本质上是一个 QuerySet 对象 ,而不是真的列表print(res_list) # <QuerySet [('xiaomeng', 18)]># 该语句可以查看当前执行命令的 SQL 语句 - 只有queryset对象才能使用该方法print(res_list.query) # SELECT `app01_user`.`name`, `app01_user`.`age` FROM `app01_user`# (8) distinct() - 去重(带有主键就意味着数据存在不一样的地方,所以一定要去除主键后再去重)# distinct 方法在主键存在时,无法对含有不同主键的相同数据进行去重# 但是我们可以通过拿到指定字段的数据后,对筛选出的数据进行去重res = models.User.objects.values('name', 'age').distinct()print(res)# (9) order_by() - 排序# 默认升序res = models.User.objects.order_by('age')print(res)# 降序res = models.User.objects.order_by('-age')print(res)# (10) reverse() - 反转的前提是数据已经经过排序过的数据# 只能对有序的数据进行反转res = models.User.objects.order_by('age').reverse()print(res)# (11) count() - 统计当前数据的个数res = models.User.objects.count()print(res)# (12) exclude() - 排出在外# 将某个数据排出在结果之外res = models.User.objects.exclude(user="dream")# (13) exists() - 是否存在 - 返回布尔值 - 用处不大,因为数据本身就有布尔值的状态res = models.User.objects.filter(pk=5).exists()print(res)
(2)方式二
所有SQL语句都可以使用
LOGGING = {'version': 1,'disable_existing_loggers': False,'handlers': {'console':{'level':'DEBUG','class':'logging.StreamHandler',},},'loggers': {'django.db.backends': {'handlers': ['console'],'propagate': True,'level':'DEBUG',},}
}
4.双下划线查询
# 神奇的双下划线查询# (1)年龄大于35岁的数据res = models.User.objects.filter(age__gt=35)print(res)# (2)年龄小于35岁的数据res = models.User.objects.filter(age__lt=35)print(res)# (3)年龄大于等于35岁的数据res = models.User.objects.filter(age__gte=35)print(res)# (4)年龄小于等于35岁的数据res = models.User.objects.filter(age__lte=35)print(res)# (5)年龄是18或者32或者40res = models.User.objects.filter(age__in=(18, 32, 40))print(res)# (6)年龄是18-40之间 - 首尾都要res = models.User.objects.filter(age__range=(18, 40))print(res)# (7)查询出名字中含有 n 的数据 -- 模糊查询res = models.User.objects.filter(name__contains='n')print(res)# (7.1)是否区分大小写?res = models.User.objects.filter(name__contains='N')print(res)# 默认区分大小写# (7.2)忽略大小写res = models.User.objects.filter(name__icontains='N')print(res)# (8)以什么开头/结尾res = models.User.objects.filter(name__startswith='d')print(res)res = models.User.objects.filter(name__endswith='m')print(res)# (9)查询出注册时间是2020年1月份的数据/年/月/日res = models.User.objects.filter(register_time__month='1')print(res)res = models.User.objects.filter(register_time__year='2020')print(res)res = models.User.objects.filter(register_time__day='28')print(res)