目录
一.过滤器
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 arg
return 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 << 10
MB = 1 << 20
GB = 1 << 30
TB = 1 << 40
PB = 1 << 50
negative = bytes_ < 0
if 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" % value
return 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 + arg
except 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 os
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day07.settings")
import django
django.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="注册时间")
'''
DateField
DateTimeField
两个关键参数
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 pymysql
pymysql.install_as_MySQLdb()
2.单表的操作
create
update
delete
all
first
filter
(1)数据的增加
from django.test import TestCase
# Create your tests here.
import os
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day07.settings")
import django
django.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 os
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day07.settings")
import django
django.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或者40
res = 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)