django框架之模板层
模板层
标签
过滤器
自定义标签、过滤器、inclusion_tag
模板的继承
模板的导入
1. 后端向前端页面传递数据
1)有两种方式
方式1:
return render(request, 'index.html', {'n': n})
方式2:将当前所在的名称空间中的变量名全部传递给前端页面
return render(request, 'index.html', locals())
后端可以给html传递的数据有哪些:
python所有的基本数据类型
函数名(传函数名会自动加括号执行,不支持传参)
对象(相当于在前端页面打印了该对象)
2)前端调用数据
前端可以调用python自带的不需要传参内置方法
前端获取后端传递过来的容器类型的内部元素,统一采用句点符:
有序类型 直接(.索引)访问
字典 直接(.key)
{{ t }},{{ t.1 }} 数字对应的就是数据的索引
模板语法
{# 模板语法的注释,不会展示到前端页面 #}
<!--原生html的注释,会展示到前端页面-->
2. 前端对数据的修饰
两种特殊符号:
{{ }} 变量相关
{% %} 逻辑相关
取消转义:
前端:|safe *****
后端:
from django.utils.safestring import mark_safe mark_safe('<h1>我是h1标签</h1>')
1)过滤器
{{ value|filter_name:参数 }}
会将|前的数据作为参数传递给后面的函数
{{ s|length }} 统计字符串的长度 {{ flag|default:'xxx' }} 获取数据,为空就返回default后面默认的参数值"xxx" {{ ctime|date:'Y-m-d'}} 格式化时间(不要加百分号%) {{ str|slice:'0:8'}} 字符串的切片操作{{ str|slice:'0:8:2'}} {{ str|truncatechars:10}} 截取规定长度的字符串,以...结尾 {{ str|truncatewords:4}} 按照空格截取文本内容 {{ n|add:1}} 同类型拼加,否则返回"" {{ file_size|filesizeformat}} 将数字格式化成表示文件大小的单位 {{ 标签文本|safe}} 取消转义,防止脚本攻击页面,告诉页面safe,则会执行标签 后端取消转义:
2)标签
♡ for循环
{#l = ['a', 'b', 'c', 'd', 'e']#} {% for foo in l %} <p>{{ foo }}</p> {% endfor %} 输出: a b c d e
forloop:自定义对象
forloop.first 判断是否为第一个(布尔值)
forloop.last 判断是否为最后一个(布尔值)
forloop.counter0 当前循环的索引值
forloop.counter 当前循环的索引值,从1开始
forloop.revcounter 未循环数+1
forloop.revcounter0 未循环数
forloop.parentloop 本层循环的外层循环{}
{#l = ['a', 'b', 'c', 'd', 'e']#} {% for foo in l %} <p>{{ forloop }}</p> {% endfor %} 输出:
a {'parentloop': {}, 'counter0': 0, 'counter': 1, 'revcounter': 5, 'revcounter0': 4, 'first': True, 'last': False} b {'parentloop': {}, 'counter0': 1, 'counter': 2, 'revcounter': 4, 'revcounter0': 3, 'first': False, 'last': False} c {'parentloop': {}, 'counter0': 2, 'counter': 3, 'revcounter': 3, 'revcounter0': 2, 'first': False, 'last': False} d {'parentloop': {}, 'counter0': 3, 'counter': 4, 'revcounter': 2, 'revcounter0': 1, 'first': False, 'last': False} e {'parentloop': {}, 'counter0': 4, 'counter': 5, 'revcounter': 1, 'revcounter0': 0, 'first': False, 'last': True}
♡ if 判断
if语句支持 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判断。
{#i = []#} {% if i %} <p>i不为空</p> {% else %} <p>i为空</p> {% endif %}
♡ for & if 嵌套使用
循环变量为空时,会执行empty后面的代码;
不为空,执行if判断。如容器中元素较少时,优先执行forloop.first,还有元素才会执行forloop.last,前两条执行完毕多出来的元素才会执行else
列表循环
{# l = ['a', 'b', 'c', 'd', 'e'] #} {% for foo in l %} {% if forloop.first %} <p>这是l第一次循环</p> {% elif forloop.last %} <p>这是l最后一次循环</p> {% else %} <p>在路上...</p> {% endif %} {% empty %} <p>容器类型为空,无法for循环!!!!</p> {% endfor %} 输出: 这是l第一次循环 在路上... 在路上... 在路上... 这是l最后一次循环 {# 换为 i = [] #} 容器类型为空,无法for循环!!!!
字典循环
起别名:当名称过长时可以起别名,只能在with内部是使用,并且本名在with内部也可以使用
{% with d.hobby.1 as h %}
<p>{{ h }}</p>
{% endwith %}
{#d = {'name': 'Tom', 'password': '222', 'hobby': ['看书', '写字']}#} {% for foo in d %} <p>{{ foo }}</p> {% endfor %} {% for foo in d.keys %} <p>{{ foo }}</p> {% endfor %} {% for foo in d.values %} <p>{{ foo }}</p> {% endfor %} {% for foo in d.items %} <p>{{ foo }}</p> {% endfor %} <p>{{ d.hobby.1 }}</p> {% with d.hobby.1 as h %} <p>{{ h }}</p> <p>{{ d.hobby.1 }}</p> {% endwith %} 输出: name # d password hobby name # d.keys password hobby Tom # d.values 222 ['看书', '写字'] ('name', 'Tom') #d.items ('password', '222') ('hobby', ['看书', '写字']) 写字 写字 写字
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^index/', views.index), url(r'^reg/', views.reg), url(r'^home/', views.home), url(r'^login/', views.login), ]
from django.shortcuts import render from django.utils.safestring import mark_safe from datetime import datetime def index(request): n = 6969 s = '你好!' i = [] l = ['a', 'b', 'c', 'd', 'e'] d = {'name': 'Tom', 'password': '222', 'hobby': ['看书', '写字']} t = ('red', 'blue', 'green') st = {'rain', 'sun'} st = '<h1>今天天气真好!</h1>' xxx = mark_safe(st) res = 'hello baby~~ bay~bay~bay~~~' file_size = 215492235 sr = '<script>alert(123)</script>' ctime = datetime.now() def func(): return '被调用了?' class Demo(object): def __init__(self, name): self.name = name def func(self): return self.name @classmethod def index(cls): return 'cls' @staticmethod def bar(): return 'bar' def __str__(self): return "谁?" obj = Demo('Tom') # return render(request, 'index.html', {'n': n}) return render(request, 'index.html', locals()) def home(request): return render(request, 'home.html') def login(request): return render(request, 'login.html') def reg(request): return render(request, 'reg.html')
3)自定义标签、过滤器、inclusion_tag
♤ 自定义必须做的三件事:
1. 在应用名下新建一个名为 templatetags文件夹(必须叫这个名字)
2. 在该新建的文件夹内新建一个任意名称的py文件
3. 在该py文件中需要固定写下面两句代码
from django import template register = template.Library()
♤ 关于自定义
自定义标签:只能传两个值
自定义过滤器:可以传多个值
自定义 inclusion_tag:支持一个变量的预备模板
使用自定义的过滤器、标签、inclusion_tag: 必须先在需要使用的html页面加载你的py文件
在要使用的.html页面导入
{% load my_tags %}
示例:my_tags.py
from django import template register = template.Library() # 自定义过滤器 @register.filter(name='and') def index(a, b): return a + b # 自定义标签 @register.simple_tag(name='aaa') def plus(a, b, c): return a + b + c # 自定义inclusion_tag @register.inclusion_tag('logino.html', name='login') # 将数据放到‘logino.html’渲染后返回给目标页面 def login(n): # l = [] # for i in range(n): # l.append('第%s个' % i) l = ['第%s个'%i for i in range(n)] return {'l': l} # 字典字典!!!
logino.html文件 :将其他的标签都删除,只放下面的代码
<ul> {% for foo in l %} <li>{{ foo }}</li> {% endfor %} </ul>
前端.html调用:
{% load my_tags %} # 加载my_tags.py文件
{{ n|and:6 }} # 自定义过滤器
{% aaa 1 2 3 %} # 自定义标签
{% login 5 %} # 自定义inclusion_tag
4)模板的继承与导入
♤ 首先需要在被继承的模板中划分多个区域
{% block 给区域起的名字 %}
被划分的区域代码
{% endblock %}
通常情况下,一个模板中至少有三个区域:
css:页面css代码块
js:页面js代码块
content:页面主体内容
♤ 子板继承模板
将模板清空
先继承模板所有内容
然后根据block块的名字修改指定区域的内容
{% extends 'home.html' %} {# 继承模板所有内容 #} {% block content %} <h1>注册页面</h1> <form action=""> <p>username:<input type="text" class="form-control"></p> <p>password:<input type="text" class="form-control"></p> <input type="submit" class="btn btn-danger pull-right" > </form> {% endblock %}
♤ 模板的导入
将一段html当做模块导入到另一个.html文件页面展示
{% include '想导入的.html文件'%}
5)静态文件配置
动态获取前缀,代码放在head标签里面
{% load static %} <link rel='stylesheet' href="{% static 'css/mycss.css'%}"> # 第一种方式 <link rel='stylesheet' href="{% get_static_prefix %}css/mycss.css"> # 第二种方式 >