一.Django------模板层
1.模板简介
模版语法重点:
变量:{{ 变量名 }}
1 深度查询 用句点符
2 过滤器
标签:{{% % }}
2.模版语法之变量
views.py
from django.shortcuts import render
from django.utils.safestring import mark_safe
# Create your views here.
class Person:
def __init__(self, name):
self.name = name
@classmethod
def class_test(cls):
print('class method')
return 'class method'
def test(self):
print('method')
return self.name
# def __str__(self):
# return self.name
def index(request):
s = 'hello'
n = 12
l1 = [1, 2, 'tom',[2,3]]
d1 = {'name': 'tom', 'age': 17}
b = True
lqz = Person('lqz')
egon = Person('egon')
monkey = Person('monkey')
l2 = [lqz, egon, monkey]
d2 = {'n1': lqz, 'n2': egon}
l3 = []
s2 = ''
d3 = {}
s3 = '<a href="https://www.baidu.com">点我</a>'
s3 = mark_safe(s3)
import datetime
now = datetime.datetime.now()
file =1024*1024*1024
# locals()会把index函数里面的所有的都能取得到
return render(request, 'index.html',locals())
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模板</title>
<link rel="stylesheet" href="/static/css">
</head>
<body>
<hr>
字符串:{{ s }}<br>
数字:{{ n }}<br>
列表:{{ l1 }}<br>
列表取值:{{ l1.3.0 }}<br>
字典:{{ d1 }}<br>
字典取值:{{ d1.name }}<br>
布尔值:{{ b }}<br>
对象:{{ lqz }}<br>
对象取值:{{ lqz.name }}<br>
对象方法(不用加括号):{{ lqz.test }}<br>
类方法:{{ lqz.class_test }}<br>
列表对象:{{ l2 }}<br>
列表对象取值:{{ l2.0.name }}<br>
对象字典:{{ d2 }}<br>
对象字典取值:{{ d2.n1.name }}<br>
空列表的情况:{{ l3 }}<br>
空字符串的情况(直接替换成空):{{ s2 }}<br>
空字典的情况:{{ d3 }}<br>
标签: {{ s3 }}<br>
字典:{{ d1.name.upper }}
<hr>
冒号后不能加空格,now是第一个参数,冒号后面是第二个参数 <br>
date过滤器:{{ now|date:"Y-m-d" }}<br>
date过滤器:{{ now|date:"Y-m-d H:i:s" }}
<hr>
如果一个变量是false或者空,使用给定的默认值,否则,使用变量的值 <br>
default过滤器:{{ s2|default:'字符串没有值' }}<br>
default过滤器:{{ l3|default:'字符串没有值' }}<br>
<hr>
length过滤器:{{ l2|length }}<br>
<hr>
将内容转换为一个文件尺寸(KB,MB,GB...) <br>
filesizeformat过滤器:{{ file|filesizeformat }}<br>
filesizeformat过滤器:{{ 1024|filesizeformat }}<br>
filesizeformat过滤器:{{ '1024'|filesizeformat }}<br>
<hr>
slice过滤器(切片):{{'lqzisbig'|slice:'1:4' }} <br>
<hr>
truncatechars过滤器(截断):{{ 'lqzisbigandegon'|truncatechars:9 }}<br>
truncatewords过滤器(截断):{{ 'lqz is big and egon is small'|truncatewords:6 }}<br>
safe过滤器(可以在视图函数处理):{{ s3|safe }}<br>
</body>
</html>
模板之过滤器
-
default 如果一个变量是false或者为空,使用给定的默认值。否则,使用变量的值。
-
length 返回值的长度。它对字符串和列表都起作用。
-
filesizeformat 将值格式化为一个文件尺寸 (例如
'13 KB'
,'4.1 MB'
,'102 bytes'
, 等等)。 -
date
-
slice
-
truncatechars
-
truncatewords
-
safe
-
其他过滤器
过滤器 描述 示例 upper 以大写方式输出 {{ user.name | upper }} add 给value加上一个数值 {{ user.age | add:”5” }} addslashes 单引号加上转义号 capfirst 第一个字母大写 {{ ‘good’| capfirst }} 返回”Good” center 输出指定长度的字符串,把变量居中 {{ “abcd”| center:”50” }} cut 删除指定字符串 {{ “You are not a Englishman” | cut:”not” }} date 格式化日期 default 如果值不存在,则使用默认值代替 {{ value | default:”(N/A)” }} default_if_none 如果值为None, 则使用默认值代替 dictsort 按某字段排序,变量必须是一个dictionary {% for moment in moments | dictsort:”id” %} dictsortreversed 按某字段倒序排序,变量必须是dictionary divisibleby 判断是否可以被数字整除 {{ 224 | divisibleby:2 }} 返回 True
escape 按HTML转义,比如将”<”转换为”<” filesizeformat 增加数字的可读性,转换结果为13KB,89MB,3Bytes等 {{ 1024 | filesizeformat }} 返回 1.0KB
first 返回列表的第1个元素,变量必须是一个列表 floatformat 转换为指定精度的小数,默认保留1位小数 {{ 3.1415926 | floatformat:3 }} 返回 3.142 四舍五入 get_digit 从个位数开始截取指定位置的数字 {{ 123456 | get_digit:’1’}} join 用指定分隔符连接列表 {{ [‘abc’,’45’] | join:’’ }} 返回 abc45 length 返回列表中元素的个数或字符串长度 length_is 检查列表,字符串长度是否符合指定的值 {{ ‘hello’| length_is:’3’ }} linebreaks 用 或
标签包裹变量{{ “Hi\n\nDavid”|linebreaks }} 返回 Hi
David
linebreaksbr 用
标签代替换行符linenumbers 为变量中的每一行加上行号 ljust 输出指定长度的字符串,变量左对齐 {{‘ab’|ljust:5}}返回 ‘ab ’ lower 字符串变小写 make_list 将字符串转换为列表 pluralize 根据数字确定是否输出英文复数符号 random 返回列表的随机一项 removetags 删除字符串中指定的HTML标记 {{value | removetags: “h1 h2”}} rjust 输出指定长度的字符串,变量右对齐 slice 切片操作, 返回列表 {{[3,9,1] | slice:’:2’}} 返回 [3,9] {{ 'asdikfjhihgie' | slice:':5' }} 返回 ‘asdik’
slugify 在字符串中留下减号和下划线,其它符号删除,空格用减号替换 {{ '5-2=3and5 2=3' | slugify }} 返回 5-23and5-23
stringformat 字符串格式化,语法同python time 返回日期的时间部分 timesince 以“到现在为止过了多长时间”显示时间变量 结果可能为 45days, 3 hours timeuntil 以“从现在开始到时间变量”还有多长时间显示时间变量 title 每个单词首字母大写 truncatewords 将字符串转换为省略表达方式 {{ 'This is a pen' | truncatewords:2 }}返回``This is ...
truncatewords_html 同上,但保留其中的HTML标签 {{ '<p>This is a pen</p>' | truncatewords:2 }}返回``<p>This is ...</p>
urlencode 将字符串中的特殊字符转换为url兼容表达方式 {{ ‘http://www.aaa.com/foo?a=b&b=c’ | urlencode}} urlize 将变量字符串中的url由纯文本变为链接 wordcount 返回变量字符串中的单词数 yesno 将布尔变量转换为字符串yes, no 或maybe {{ True | yesno }}{{ False | yesno }}{{ None | yesno }} ``返回 ``yes``no ``maybe
3.模板之标签
for标签
遍历每一个元素:
{% for person in person_list %}
<p>{{ person.name }}</p>
{% endfor %}
可以利用{% for obj in list reversed %}反向完成循环。
遍历一个字典:
{% for key,val in dic.items %}
<p>{{ key }}:{{ val }}</p>
{% endfor %}
循环序号可以通过{{forloop}}显示
forloop.counter 当前循环的索引值(从1开始)
forloop.counter0 当前循环的索引值(从0开始)
forloop.revcounter 当前循环的倒序索引值(从1开始)
forloop.revcounter0 当前循环的倒序索引值(从0开始)
forloop.first 当前循环是不是第一次循环(布尔值)
forloop.last 当前循环是不是最后一次循环(布尔值)
forloop.parentloop 本层循环的外层循环
循环序号可以通过{{forloop}}显示
{% for foo in l1 %}
<p>{{ forloop }}</p>
<p>{{ forloop.counter }}</p>
<p>{{ forloop.counter0 }}</p>
<p>{{ forloop.revcounter }}</p>
<p>{{ forloop.revcounter0 }}</p>
<p>{{ forloop.first }}</p>
<p>{{ forloop.last }}</p>
<p>{{ forloop.parentloop }}</p>
<p>{{ foo }}</p>
{% endfor %}
forloop.counter 当前循环的索引值(从1开始)
forloop.counter0 当前循环的索引值(从0开始)
forloop.revcounter 当前循环的倒序索引值(从1开始)
forloop.revcounter0 当前循环的倒序索引值(从0开始)
forloop.first 当前循环是不是第一次循环(布尔值)
forloop.last 当前循环是不是最后一次循环(布尔值)
forloop.parentloop 本层循环的外层循环
for 标签带有一个可选的{% empty %} 从句,以便在给出的组是空的或者没有被找到时,可以有所操作。empty一定要放在for循环中
{% for person in person_list %}
<p>{{ person.name }}</p>
{% empty %}
<p>sorry,no person here</p>
{% endfor %}
if标签
{% if %}会对一个变量求值,如果它的值是“True”(存在、不为空、且不是boolean类型的false值),对应的内容块会输出。
{% if num > 100 or num < 0 %}
<p>无效</p>
{% elif num > 80 and num < 100 %}
<p>优秀</p>
{% else %}
<p>凑活吧</p>
{% endif %}
if语句支持 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判断。
with
{% with d1.name as t %}
相当于重新赋值
<p>{{ t }}</p>
<p>{{ t }}</p>
{% endwith %}
{% with b=d1.name %}
<p>{{ b }}</p>
{% endwith %}
4.自定义标签和过滤器
自定义过滤器
1.先去settings里面把app名字配置上
2.在app目录下创建一个templatetags文件夹
3.写py文件(my_test.py)
4.from django import template
5.register = template.Library() # register的名字是固定的,不可改变
6.写函数(用register.filter()装饰)
@register.filter(name='tt')
def addrstr(x,y):
return x+y
7.在html模板:
{% load my_test %}
{{ 'tom'|tt:'iscool' }}
自定义标签
1.先去settings里面把app名字配置上
2.在app目录下创建一个templatetags文件夹
3.写py文件(my_test.py)
4.from django import template
5.register = template.Library() # register的名字是固定的,不可改变
6.写函数(用register.simple_tag()装饰)
@register.simple_tag(name='yy')
def my_sum(x,y,z):
return x+y+z
7.在html模板:
{% load my_test %}
{% yy 2 3 4 %}
两者的区别:
自定义过滤器可以写在if判断条件里面,而自定义标签不行
{% if 'tom'|tt:'iscool' %}
自定义过滤器可以放在if判断条件里
自定义标签不可以
{% endif %}
5.静态文件相关
{% load static %}
<img src="{% static "images/hi.jpg" %}" alt="Hi!" />
引用JS文件时使用:
{% load static %}
<script src="{% static "mytest.js" %}"></script>
某个文件多处被用到可以存为一个变量
{% load static %}
{% static "images/hi.jpg" as myphoto %}
<img src="{{ myphoto }}"></img>
使用get_static_prefix
{% load static %}
<img src="{% get_static_prefix %}images/hi.jpg" alt="Hi!" />
或者
{% load static %}
{% get_static_prefix as STATIC_PREFIX %}
<img src="{{ STATIC_PREFIX }}images/hi.jpg" alt="Hi!" />
<img src="{{ STATIC_PREFIX }}images/hi2.jpg" alt="Hello!" />
6.模板导入与继承
6.1模板导入
1. 把公共部分,放在html里面,比如:common.html
2. 想在哪里用,就用{% include 'common.html' %}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.css">
<style>
.head {
height: 50px;
width: 100%;
background: #ff6700;
}
</style>
</head>
<body>
<div class="container">
<div class="head text-center">
<h1>全球最大的同志相亲平台</h1>
</div>
<div class="row">
<div class="col-md-3">
{% include 'common.html' %}
</div>
<div class="col-md-9">
<div>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Amet, voluptatibus?</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Amet, voluptatibus?</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Amet, voluptatibus?</p>
</div>
</div>
</div>
</div>
</body>
</html>
common.html
<div>
<div class="panel panel-danger">
<div class="panel-body">
Panel content
</div>
<div class="panel-footer">Panel footer</div>
</div>
<div class="panel panel-success">
<div class="panel-body">
Panel content
</div>
<div class="panel-footer">Panel footer</div>
</div>
<div class="panel panel-info">
<div class="panel-body">
Panel content
</div>
<div class="panel-footer">Panel footer</div>
</div>
</div>
6.2母板继承
1. 写一个母版 base.html
写一个使用者test.html
urls.py 写路由,路由地址为test/
url(r'^test/', views.test)
views.py写一个函数test,return到test.html
def test(request):
return render(request,'test.html')
2.在base.html中,要更改的地方
{% block base %}
母板的盒子也可以写东西
{% endblock base %}
3.在test.html调用:
1.{% extends 'base.html' %}写在首行
2.{% block base %}
写自己的东西
{% endblock %}
3.还想要母板里的内容
(记住还是在test.html中,{{block.super}}放在哪,母板的东西就会渲染到那):
{% block base %}
{{block.super}}
自己的东西
{% endblock %}
4.如果不继承盒子,它会用原来的内容,如果继承了,没写自己的东西,它会空白
5.盒子在继承跟顺序无关
base.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
{% block base2 %}
<title>index首页</title>
{% endblock %}
<link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.css">
<style>
.head {
height: 50px;
width: 100%;
background: #ff6700;
}
</style>
</head>
<body>
<div class="container">
<div class="head text-center">
<h1>全球最大的同志相亲平台</h1>
</div>
<div class="row">
<div class="col-md-3">
{% block left %}
{% endblock left %}
</div>
<div class="col-md-9">
{% block base %}
<h1>我是内容区域</h1>
{% endblock base %}
</div>
</div>
</div>
</body>
</html>
test.html
{% extends 'base.html' %}
{% block base2 %}
<title>订单页面</title>
{% endblock base2 %}
{% block left %}
{% include 'left.html' %}
{% endblock left %}
{% block base %}
{{ block.super }}
<p>Lorem ipsum dolor sit amet.</p>
<p>Lorem ipsum dolor sit amet.</p>
{% endblock base %}
urls.py
urlpatterns = [
url(r'^test/', views.test),
]
views.py
def test(request):
return render(request,'test.html')
6.3 自定义 inciusion_tag(了解)
1.先去settings里面把app名字配置上
2.在app目录下创建一个templatetags文件夹
3.写py文件(my_test.py)
4.from django import template
5.register = template.Library() # register的名字是固定的,不可改变
6.写函数(用register. inciusion_tag()装饰)
@register.inciusion_tag('my_li.html')
def my_inclusion(n):
data = []
for i in range(n):
data.append('第%s行' % (i + 1))
return {'data': data}
7.写my_li.html页面
8.在my_test.html页面:
{% load my_test %}
{% my_inclusion 10 %}
得到的是生成了10行li页面
my_li.html
<ul>
{% for choice in data %}
<li>{{ choice }}</li>
{% endfor %}
</ul>
my_test.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>my_test</title>
</head>
<body>
{% load my_test %}
{% show_results 10 %}
</body>
</html>