基本语法结构如下:
{{数据对象|过滤器名称:参数}} 过滤器最多只能额外传输一个参数
统计数据的长度
<p>{{ s1|length }} </p>
算数加法或者是字符串拼接
<p> 算数加法{{ n1|add:111 }}、字符串拼接{{ s1|add:'big bady' }}</p>
将数字转换成合适的文件计量单位
<p> {{ file_size|filesizeformat }} </p>
判断当前数据对象对应的布尔值是否是False
'''
如果当前对象布尔值是False时获取default后所携带的值
若不是则会获取前面的数据的值
'''
b = False
<p>{{ b|default:'前面的值对应的布尔值是False' }}</p>
# 获取 —— 前面的值对应的布尔值是False
<p>{{ s1|default:'前面的值对应的布尔值是False' }}</p>
# 获取 —— s1 指定的值
时间格式化:
'''
将时间格式数据再页面上格式化展示
'''
<p>{{ ctime|date:'Y-m-d' }}</p>
索引切片:
'''
根据索引切割字符串
'''
<p> {{s1|slice:'0:3'}}</p>
按照空格截取指定个数的文本:
<p>{{ s2|truncatewords:5 }}、{{ s1|truncatewords:1 }}</p>
按照字符个数截取文本(包含三个点)
<p>{{ s2|truncatechars:5 }}、{{ s1|truncatechars:10 }}</p>
移除指定的字符:
<p>{{ info|cut:'|' }}</p>
是否取消转换:
'''
safe是取消转换的关键字
'''
<p> 是否取消转换:{{ tag1 }}、{{ tag1|safe }}</p>
'''
上述是前端取消转换的方式 也可以在后端取消转换
需要在后端导入以下这个模块
from django.utils.safestring import mark_safe
然后用一个变量名去接收mark_safe生成的结果
res = mark_safe(tt)
'''
<p>{{ res }}</p>
在django模板语法中写标签的时候 只需要写关键字然后tab键就会自动补全
语法结构如下:
{% 名字 ...%}
{% end名字 %}
语法结构如下:
{% if b %}
<p>当b的布尔值为Ture会执行的语句</p>
{% elif s1 %}
<p>当s1的布尔值为Ture会执行的语句</p>
{% else %}
<p>当上述值的布尔都为Flase会执行的语句</p>
{% endif %}
{% for foo in l1 %}
<p>{{ foo }}</p>
{% endfor %}
在for循环中提供了forloop关键字,关键字的内容如下:
{'parentloop': {}, 'counter0': 0, 'counter': 1, 'revcounter': 4, 'revcounter0': 3, 'first': True, 'last': False}
{'parentloop': {}, 'counter0': 1, 'counter': 2, 'revcounter': 3, 'revcounter0': 2, 'first': False, 'last': False}
{'parentloop': {}, 'counter0': 2, 'counter': 3, 'revcounter': 2, 'revcounter0': 1, 'first': False, 'last': False}
{'parentloop': {}, 'counter0': 3, 'counter': 4, 'revcounter': 1, 'revcounter0': 0, 'first': False, 'last': True}
然后它还可以与if连用。
{% for i in l1 %}
{% if forloop.first %}
<p>这是第一次循环</p>
{% elif forloop.last %}
<p>这是最后一次循环</p>
{% else %}
<p>中间循环</p>
{% endif %}
{% empty %}
<p>for循环对象为空 自动执行</p>
{% endfor %}
ps:针对字典同样提供了keys、values、items
想要自定义以上几种,我们需要有 一个固定的步骤,操做如下:
1.在应用下需要创建一个名为templatetags文件夹
2.在该文件夹内创建任意名称的py文件
3.在该py文件内需要先提前编写两行固定的代码
from django import template
register = template.Library()
定义格式:
@register.filter(is_safe=True)
def index(a, b):
return a+b
使用格式:
{% load mytag %} # 先加载自己写的过滤器文件夹
{{ n1|index:666 }} # 使用过滤器
定义格式:
@register.simple_tag(name='my_tag')
def func1(a, b, c, d):
return a+b+c+d
使用格式
{% load mytag %}
{% my_tag 1 2 3 4 %} # 参数之间空格隔开即可
相当于在一个页面封装了一个代码用于快速产生HTML代码的方法。
定义格式:
@register.inclusion_tag('left.html')
def func2(n):
l1 = []
for i in range(1, n+1):
l1.append(f'第{i}页')
return locals()
<ul>
{% for foo in l1 %}
<li>{{ foo }}</li>
{% endfor %}
</ul>
使用格式
{% load mytag %}
{% func2 %}
类似于将html页面上的局部页面做成模块的形式 哪个地方想要直接导入即可展示
eg:有一个非常好看的获取用户数据的页面 需要在网站的多个页面上使用
策略1:拷贝多份即可
策略2:模板的导入
使用方式
{% include 'menu.html' %}
<!----> 是HTML的注释语法
{##} 是django模板语法的注释
"""
HTML的注释可以在前端浏览器页面上直接查看到
模板语法的注释只能在后端查看 前端浏览器查看不了
"""
类似于面向对象的继承:继承了某个页面就可以使用该页面上所有的资源。
有很多网站的很多页面 其实都是差不多的 只是局部有所变化 模板的继承可以很好的实现该需求。
1.先在模板中通过block划定将来可以被修改的区域
{% block content %}
<h1>主页内容</h1>
{% endblock %}
2.子板继承模板
{% extends 'home.html' %}
3.修改划定的区域
{% block content %}
<h1>登录内容</h1>
{% endblock %}
4.子页面还可以重复使用父页面的内容
{{ block.super }}
"""
模板上最少应该有三个区域
css区域、内容区域、js区域
子页面就可以有自己独立的css、js、内容
"""
'''
django自带的sqlite3数据库 功能很少 并且针对日期类型不精确
1.数据库正向迁移命令(将类操作映射到表中)
python3 manage.py makemigrations
python3 manage.py migrate
2.数据库反向迁移命令(将表映射成类)
python3 manage.py inspectdb
'''
当我们只想操作orm 不想使用网络请求,就需要搭建专门的测试环境,具体操做如下:
1.自己搭建
import os
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day54.settings")
import django
django.setup()
2.pycharm提供
python console
res = models.User.objects.all()
# 查询所有的数据 结果是QuerySet可以看成列表套对象
res = models.User.objects.filter()
# 括号内填写筛选条件 不写相当于是all()
res = models.User.objects.filter(pk=1)
# 想通过主键筛选数据 可以直接写pk会自动定位到当前表的主键字段 无需自己查看具体主键字段
res = models.User.objects.filter(pk=1)[0]
# 直接获取数据对象 QuerySet支持索引取值 但是django不推荐使用
res = models.User.objects.filter(pk=1).first()
# 获取结果集中的第一个对象 推荐使用封装的方法 不会出现索引超出范围报错
res = models.User.objects.filter(pk=1,name='kevin').first()
# 括号内支持填写多个筛选条件 默认是and关系
res = models.User.objects.filter().filter().filter().filter().filter()
# 只要是QuerySet对象就可以继续点对象方法
res = models,User.objects.filter().last()
# 获取结果集中最后一个对象
res = models.User.objects.all().values('name','age')
# QuerySet 可以看成是列表套字典
res = models.User.objects.values('name', 'age')
# QuerySet 可以看成是列表套字典 指定字段all不写也表示从所有数据中操做
res = models.User.objects.filter(pk=2).values('name')
# values 可以看成是对结果集进行字段的筛选
res = models.User.objects.all().values_list('name', 'age')
# QuerySet 可以看成是列表套元组
'''
去重
'''
res = models.User.object.all().distinct()
# 数据对象中包含主键不可以去重
res = models.User.object.values('name').distinct()
'''
排序
'''
res = models.User.object.order_by('age')
# 默认是升序
res = models.User.object.order_by('-age')
# 降序
res = models.User.object.order_by('age', 'pk')
# 支持排序多个字段
'''
取反
'''
res = models.User.objects.exclude(name='jason')
# 取反操做 不拿name = jason的值
'''
计数
'''
res = models.User.objects.count()
# 统计结果集的个数
'''
判断数据集是否为空
'''
res = models.User.objects.filter(name='jasonNB').exists()
# 判断结果集是否又数据 有True 无Flase