Django模板系统
一、初识模板
变量 {{ 变量名 }}
逻辑操作{% 逻辑操作 %}
点操作在模板语言中是 用于获取对象的相应属性值得。
views.py
1 def test(request): 2 l_test = ['小李飞刀 ', '一双绣花鞋', '暗夜心慌慌'] 3 d_test = {'nut': 'coconut', 'fruit':'apple', 'bird': 'wing'} 4 5 class Program(object): 6 7 def __init__(self, name, host): 8 self.name = name 9 self.host = host 10 11 def clown(self): 12 return '{} is very funny'.format(self.name) 13 14 amune = Program('谢娜', '快乐大本营') 15 elegant = Program('汪涵', '天天向上') 16 17 program_list = [amune, elegant] 18 19 return render(request, 'test.html', {'l': l_test, 'd': d_test, 'program': program_list})
在html文件中进行点操作
{# 这是模板注释语法 #}
{# 取得列表的第二个元素 #}
{{ l.1 }}
{# 用键从字典里取值 #}
{{ d.nut }}
{# 取对象的属性 #}
{{ program.0.name }}
{# 点操作调用方法 #}
{{ program.1.clown }}
上传文件操作:
Views.py
def index(request): if request.method == 'POST': file_obj = request.FILES.get('img') file_name = file_obj.name with open(file_name, 'wb') as f: for line in file_obj.chunks(): f.write(line) print('='*120) name = request.POST.get('username') print(name) return HttpResponse(name+'OK') return render(request, 'index.html')
html文件
<form action="/index/" method="post" enctype="multipart/form-data"> <input type="text" name="username"> <input type="file" name="img"> <input type="submit" name="提交"> </form>
二、过滤器
(一)filters过滤器
{{ value|filter_name:参数 }}
1.设置默认值default
{{ value|default:’parameter’ }}
2.获取value的长度length
{{ value|length }}
3.将值格式化为文件尺寸filesizeformat
{{ file_name|filesizeformat }}
4.切片slice
{{value|slice:"2:-1"}}
5.格式化时间date
{{ today|date }}
6.safe
为了安全,django会对HTML标签和JS等语法标签自动转义。关闭Django中的自动转义有两种方法:
第一种:
{% autoescape off %} {# 这是在py文件里传来的 #} {{ h1 }} {# 这是从当前html传来的 #} {{ '<strong>this is a code from html</strong>' }} {% endautoescape %}
第二种:
{{ '<h1>this is safe code'|safe }}
(二)turncatechars截断显示
如果字符串多于指定的字符数量将会被截断截断的字符串将可以翻译的省略号序列结尾
{{ turn|truncatechars:150 }}
(三)自定义filter
在app里新建名字为templatetags的python package
在包里创建一个存放自制filter的py文件
在py文件里
from django import template register = template.Library() @register.filter(name="cut") def cut(value, arg): return value.replace(arg, "") @register.filter(name="add_wg") def add_wg(value): return "{} 山上".format(value)
在html文件里
{# 先导入我们自定义filter那个文件 #}
{% load xx %}
{# 使用我们自定义的filter #}
{{ 'cut'|cut:"0" }}
{{ 'aa'|add_wg }}
三、for标签
for…endfor
<ul> {% for user in user_list %} <li>{{ user.name }}</li> {% endfor %} </ul>
参数
{{ forloop.counter }} 当前循环的索引值(从1开始)
{{ forloop.counter0 }} 当前循环的索引值(从0开始)
{{ forloop.revcounter }} 当前循环的倒序索引值(从1开始)
{{ forloop.revcounter0 }} 当前循环的倒序索引值(从0开始)
{{ forloop.first }} 当前循环是不是第一次循环(布尔值)
{{ forloop.last }} 当前循环是不是最后一次循环(布尔值)
{{ forloop.parentloo }} 本层循环的外层循环
for…empty…endfor
<ul> {% for user in user_list %} <li>{{ user.name }}</li> {% empty %} <li>空空如也</li> {% endfor %} </ul>
四、If标签
if语句支持 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判断。
If…else…endif
{% if 条件 %}
条件成立
{% else %}
条件不成立
{% endif %}
If…elif…else…endif
{% if 条件1 %}
条件1成立
{% elif 条件2 %}
条件2成立
{% else %}
条件1,2都不成立
{% endif %}
五、With起别名
{% with 别名=原名 %}
别名应用范围
{% endwith %}
六、csrf_token
这个标签用于跨站请求伪造保护,在form表单里写{% csrf_token %}
<form action=’’ method=’post’> {% csrf_token %} 。。。。。。 </form>
CSRF扩展学习网址:CSRF 攻击的应对之道
浏览器同源策略学习网址:浏览器的同源策略
七、母版
1 <!DOCTYPE html> 2 3 <html lang="en"> 4 5 <head> 6 7 <meta charset="UTF-8"> 8 9 <meta http-equiv="x-ua-compatible" content="IE=edge"> 10 11 <meta name="viewport" content="width=device-width, initial-scale=1"> 12 13 <title>Title</title> 14 15 {# 用于给子页面替换导入的css,这种css是只有该子页面使用的 #} 16 17 {% block page-css %} 18 19 20 21 {% endblock %} 22 23 </head> 24 25 <body> 26 27 28 29 <h1>这是母板的标题</h1> 30 31 {% block page-main %} 32 33 34 35 {% endblock %} 36 37 <h1>母板底部内容</h1> 38 39 {# 用于给子页面替换导入的js,这种js是只有该子页面使用的#} 40 41 {% block page-js %} 42 43 44 45 {% endblock %} 46 47 </body> 48 49 </html>
八、子页面继承母版
在子页面的页面最上方使用以下继承
{% extends ‘layouts.html’ %}
九、组件
{% include ‘nav.html’ %}
十、静态文件相关
{% load static %}
<img src=’{% static ‘mytest.png’ %}’ alt=’’ />
(一)某个文件多处被用可以存为一个变量
{% load static %}
{% static ‘img/dog.png’ as mydog_photo %}
<img src=’{{ mydog_photo }}’></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!" />
(三)自定义simpletag
和自定义filter类似,只不过接收更灵活的参数。
定义注册simple tag
@register.simple_tag(name="plus") def plus(a, b, c): return "{} + {} + {}".format(a, b, c)
使用自定义simple tag
{% load app01_demo %}
{# simple tag #}
{% plus "1" "2" "abc" %}
(四)Inclusion_tag
多用于返回html代码片段
templatetags/my_inclusion.py
from django import template register = template.Library() @register.inclusion_tag('result.html') def show_results(n): n = 1 if n < 1 else int(n) data = ["第{}项".format(i) for i in range(1, n+1)] return {"data": data}
templates/snippets/result.html
<ul> {% for choice in data %} <li>{{ choice }}</li> {% endfor %} </ul>
templates/index.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>inclusion_tag test</title> </head> <body> {% load inclusion_tag_test %} {% show_results 10 %} </body> </html>
PS:注意事项
第一项:
a=10 b=20 c=-5
连续判断 :a>b>c
在python中相当于a>b and b>c
在javascript中相当于a>b的结果再与c进行比较
在Django的模板语言中不支持这种写法
第二项:
在Django的模板语言中属性的优先级大于方法
def xx(request): d = {"a": 1, "b": 2, "c": 3, "items": "100"} return render(request, "xx.html", {"data": d})
如上,我们在使用render方法渲染一个页面的时候,传的字典d有一个key是items并且还有默认的 d.items() 方法,此时在模板语言中:
{{ data.items }}。默认会取d的items key的值。
详细学习见:Django模板系统