django4
- 复习
- 常见过滤器
- 自定义过滤器
- 模板结构优化
- 加载静态文件
复习
settings.py 中有一个 TEMPLATES 配置
BASE_DIR 你的项目目录
'DIRS': [os.path.join(BASE_DIR, 'templates')] 项目目录下templates文件夹
也就是说 render render_to_string 会来这里 查找模板
#'DIRS': [r"C:\templates"] 可以自定义主 templates 文件夹位置
'APP_DIRS': True, 要记得 在 settings.py中
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'book' #加入你创建的应用 要不然找不到这个模板
]
APP_DIRS 为True 保证 每个app 都到自己目录下面的templates 然后将'DIRS': []为空
都没有 抛异常 templatedoesnotexists 异常
with 标签
模板中想要定义变量 可以使用with语句
{# <p>{{ people.0 }}</p>#}
{# <p>{{ people.0 }}</p>#}
{# <p>{{ people.0 }}</p>#}
这个方式 有点 麻烦
可以使用下面两种方法
{% with zelinx=people.0 %} 要求 =号前后 不能有 空格
<p>{{ zelinx }}</p>
<p>{{ zelinx }}</p>
<p>{{ zelinx }}</p>
{% endwith %}
{% with people.0 as qulinx %}
<p>{{ qulinx }}</p>
<p>{{ qulinx }}</p>
<p>{{ qulinx }}</p>
{% endwith %}
verbatim 标签
后期做项目 可能不止 DTL模板引擎 还有 https://github.com/aui/art-template 或者 vue verbatim 标签 能够让 两个模板引擎共存
项目过程中 模板引擎 可能不止django自带的 DTL 还有 VUE VUE也是{{ }} 为了让部分代码 使用vue 解析方法
可以对 这部分代码 用
{% verbatim %}
{{ 这里的代码用vue或者 art-template引擎 解析 }}
{% endverbatim %}
其它 用DTL来解析
{{ person.0 }} 这个输出的是 zhangsan
{% verbatim %}
{{ kangbazi }} 这个输出的 是 {{kangbazi}}
{% endverbatim %}
常用的过滤器
其实就是 函数 我们可以通过在 模板中定义函数 来实现 我们的 目的
在 DTL模板中 不支持 圆括号传递参数
{{greet('ee')}}
正确的语法是 :
{{value|函数名字:值}}
add
将值和参数转成整型以后进行相加 如果不能转成整型 将值和参数 进行拼接
{{value|add:参数}}
源代码 :
def add(value, arg):
"""Add the arg to the value."""
try:
return int(value) + int(arg)
except (ValueError, TypeError):
try:
return value + arg
except Exception:
return ''
示例代码:
context = {
'num1':4,
'num2':10,
}
{{ num1|add:num2}} 返回14
cut 过滤器 类似于 python中的replace 移除值中指定的字符串
{{value|cut:”“}}
{{ "hello world"|cut:"hello" }} #返回的结果 world
date 时间过滤器
{{value|date:""}}
{{ today|date:"Y-m-d h:i:s" }}
Y 四位数年份
m 两位数月份 1-9 01-09
n 1-9 前面不加0
d 两位数字的天
h 小时 12小时 0前缀
i 分钟 0前缀
s 秒 0前缀
H 小时 24小时制 0前缀
G 小时 前面没有 0前缀
default 过滤器
{{value|default:"默认值"}}
判断 value 是否为真 如果真 显示 value的值 如果为假 显示默认值
为false的情况 [] "" None {}
default_if_none
{{value|default_if_none:"默认值"}}
只有 value 值为 None的时候 才显示默认值 如果 "" [] {} 认定为真 显示空字符串 等
context = {
'value':None
}
first 返回 列表 元组 字符串的第一个元素
{{value|first}}
last 返回 列表 元组 字符串的最后一个元素
{{value|last}}
floatformat 使用四舍五入的方式 格式化 一个浮点类型
{{value|floatformat}} 默认保留一位小数点
3.00000 返回 3
3.1415 返回3.1
3.15 返回3.2 四舍五入 保留一位小数点
{{ value|floatformat:3 }} 保留3位小数点
join 将列表 元组 字符串 使用 符号进行拼接
{{value|join:"@"}}
length 列表 元组 字符串 字典的长度
{{value|length}}
lower 所有的字符串 转成小写
{{value|lower}}
upper 所有的字符串转成大写
{{value|upper}}
random 随机取出 列表 元组 字符串中的任意一值 点名器
{{value|random }}
safe
{{ value|safe }}
标记 里边的字符串是安全的 你不用给我转义
slice 类似于python中的切片操作
{{ value|slice:"0:"}}
从0开始截取到最后
{{ value|slice:"0::2"}}
context = {
'value':"0123456789"
}
输出02468
striptags 删除字符串中所有的 html标签
{{ value|striptags }}
context = {
'value':"<script>alert('我的每一支笔都知道你的名字')</script>"
}
最后输出 alert('我的每一支笔都知道你的名字')
truncatechars 如果给定的字符串超过了 过滤器要求的长度 那么就会进行切割 然后拼接 … 作为省略号
{{value|truncatechars:5}} 5这里 合理是指 2个字符+3个点
context = {
'value':"<p>小爷,欢迎下次光临</p>"
}
最后结果: <p...
truncatechars_html 如果给定的字符串超过了 过滤器要求的长度 那么就会进行切割 然后拼接 … 作为省略号 跟上面的区别是 它不切割 html标签 只切割字符串
context = {
'value':"<p>小爷,欢迎下次光临</p>"
}
{{ value|truncatechars_html:6 }}
最终结果
<p>小爷,...</p>
——————-以上都是 DTL内置过滤器 相当于系统提前给你写好的函数 但是有时候还不能满足所有的需求 这个时候需要自定义 过滤器 也叫自定义函数 记住 过滤器最多两个参数 ———-
自定义 过滤器
模板的过滤器必须放在 app中 而且这个app 必须要安装在 settings.py 的INSTALLED_APPS 中 然后在app下面创建一个 python包 这个包的名字 必须叫 templatetags 在包里再创建一个python文件
目录结构: book models.py views.py urls.py templatetags my_filter.py
到settings.py INSTALLED_APPS写上应用的名字
接下来 就是在my_filter.py写过滤器代码 但是 毕竟是python的函数 必须要将 这个过滤器 注册到 模板中 以后在这个模板中 就可以使用这个函数了
过滤器最多两个参数
过滤器的第一个参数 永远是被过滤的那个参数 也就是 | 左边 那个
然后将其注册到 模板中
最后在页面上 要 {%load my_filter%}
#### 示例代码
from django import template
register = template.Library() #这里是产生一个注册对象
def kangbazi(value,word):
return value+word
register.filter("kangbazi",kangbazi) #将其注册进去
这是在页面上显示的名字 后面是自定义的名字
{% load my_filter %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>自定义过滤器 自定义函数 </title>
</head>
<body>
{{ value|kangbazi:"下次再来" }}
</body>
</html>
from django.shortcuts import render
def index(request):
context = {
'value':'qulinx'
}
return render(request,'index.html',context=context)
# Create your views here.
自定义过滤器实战
发表微博 或者 空间动态的时候 一般不会直接显示发布的精确时间 而是 刚刚 *分钟之前 *小时之前 *天前
超过这些时间 显示 年月日 时分秒
from django import template
from datetime import datetime
register = template.Library()
def kangbazi(value,word):
return value+word
register.filter("kangbaba",kangbazi)
def time_since(value):
'''
刚刚 1分钟以内
大于1分钟 小于1小时 多少分钟之前
大于1小时 小于 24小时 几个小时之前
大于24小时 小于30天 几天前
否则 显示具体时间 2018/09/13 10:12:13
'''
now = datetime.now() #获取当前的时间
timestamp = (now-value).total_seconds() #当前时间 减去 发表时间的 间隔秒数
if timestamp < 60:
return '刚刚'
elif timestamp>=60 and timestamp<= 3600:
minutes = int(timestamp/60)
return '%s分钟之前' % minutes
elif timestamp>=60*60 and timestamp<= 60*60*24:
hours = int(timestamp/60/60)
return '%s小时之前' % hours
elif timestamp>=60*60*24 and timestamp<= 60*60*24*30:
days = int(timestamp/60/60/24)
return '%s天之前' % days
else:
return value.strftime("%Y-%m-%d %H:%M")
register.filter("times",time_since)
times是在页面上显示的过滤器名称
views.py
from django.shortcuts import render
from datetime import datetime
def index(request):
context = {
'value':'qulinx',
'mytime':datetime(year=2018,month=9,day=13,hour=15,minute=56,second=10)
}
return render(request,'index.html',context=context)
index.html
{% load my_filter %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>自定义过滤器 自定义函数 </title>
</head>
<body>
{{ value|kangbaba:"下次再来" }}
{{ mytime|times }}
</body>
</html>
模板结构优化
每个页面都包含 head 底部部分 如果说 N页面 全部在重新写一遍 有点浪费时间 如果修改 全部都要改
现在 一个办法是 把公共的部分抽离出来 其它页面只需要引入这个公共部分即可 修改的话 只需要修改公共部分一个文件即可
1.首先将相同的代码 比如 header footer 统统单独写到一个文件中 比如 header.html
其它页面只需要
{% include '文件的名字' %}
{% include '文件的名字' %}
如果想要把 原本只有 固定的页面显示的变量 在 其它页面也显示
{% include '文件的名字' with 变量名=‘值’%}
示例代码 :
{% include 'header.html' with username='haha'%}
<div class="content">
这是公司信息
</div>
{% include 'footer.html' %}
模板继承
将所有相同部分的代码 放到一个base.html中
其它页面{%extends 'base.html'%}
如果想要 显示base.html中的 特殊内容
{{block.super}}
示例代码
base.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<header>
<ul>
<li><a href="/">首页</a></li>
<li><a href="{% url 'company' %}">公司</a></li>
<li><a href="{% url 'talk' %}">言职</a></li>
{{ username }}
</ul>
</header>
<div class="content">
{% block content %}
今天下午五点开校委会 除了这里不同 其它全部相同
{% endblock %}
</div>
<footer>
欢迎下次再来 这是页脚部分
</footer>
</body>
</html>
index.html
{% extends 'base.html' %}
{% block content %}
我是首页的代码
<p>{{ block.super }}</p> 继承于 base.html 特殊的内容
{% endblock %}