经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » Django » 查看文章
django 模版语法与使用
来源:cnblogs  作者:郭楷丰  时间:2019/6/21 8:53:33  对本文有异议

django 模版语法与使用

django模板语言介绍 (摘自官方文档) 链接

  1. """
  2. Django模板语言
  3. Django的模板语言旨在在功能和易用性之间取得平衡。它让那些习惯使用HTML的人感到舒服。
  4. 如果您对其他基于文本的模板语言(如Smarty 或Jinja2)有过接触,那么您应该对Django的模板感到宾至如归。
  5. 哲学
  6. 如果您有编程背景,或者习惯于将编程代码直接混合到HTML中的语言,那么您需要记住,
  7. Django模板系统不仅仅是嵌入到HTML中的Python。这是一种设计,模板系统用于表达,而不是程序逻辑。
  8. Django模板系统提供的标签功能类似于一些编程结构 如 if,布尔,for标签,循环标签等 - 但这些标签不是简单地作为相应的Python代码执行,
  9. 模板系统不会执行任意Python表达式。默认情况下,仅支持下面列出的标记,过滤器和语法(您可以根据需要将自己的扩展添加到模板语言中)。
  10. 哲学
  11. 为什么使用基于文本的模板而不是基于XML的模板(如Zope的TAL)?我们希望Django的模板语言不仅可用于XML / HTML模板。
  12. 在World Online,我们将其用于电子邮件,JavaScript和CSV。您可以将模板语言用于任何基于文本的格式。
  13. 哦,还有一件事:让人类编辑XML是虐待狂!
  14. """

什么是模板?

  1. 模板只是一个文本文件。它可以生成任何基于文本的格式(HTMLXMLCSV等)。
  2. 模板包含变量,这些变量在评估模板时将替换为值,而变量则包含控制模板逻辑的标记。
  3. 只要是在html里面有模板语法就不是html文件了,这样的文件就叫做模板。

模板语句的 注释

  1. 模板语句的注释
  2. {#{{ '10'|add_str:'5 '}}#}
  3. {#注释内容#}

变量 {{ 变量 }}

  • 变量:语法为 {{ }}:括号里加要渲染变量的变量值,变量名由字母数字和下划线组成。

  • 代码

  1. #views 文件函数
  2. def template_test(request):
  3. name = '钢蛋'
  4. age = 18
  5. hobby = ['唱', '跳', 'rap', '篮球']
  6. lis = []
  7. st = ''
  8. dic = {
  9. 'name': '铁蛋',
  10. 'age': 16,
  11. 'hobby': hobby,
  12. 'keys': 'xxxxx'
  13. }
  14. dic_2 = {}
  15. return render(request,'template_test.html',
  16. {'name':name_p,'age':age,'hobby':hobby,'lis':lis,'st':st,'dic':dic,'dic_2':dic_2})
  17. # 模板文件html页面
  18. <!DOCTYPE html>
  19. <html lang="en">
  20. <head>
  21. <meta charset="UTF-8">
  22. <title>郭楷丰</title>
  23. </head>
  24. <body>
  25. {{ 啦啦啦啦啦 }}
  26. <p>
  27. {{ name }}
  28. </p>
  29. <p>
  30. {{ age }}
  31. </p>
  32. <p>
  33. {{ hobby }}
  34. </p>
  35. <p>
  36. {{ lis }}
  37. </p>
  38. <p>
  39. {{ st }}
  40. </p>
  41. <p>
  42. {{ dic }}
  43. </p>
  44. <p>
  45. {{ dic_2 }}
  46. </p>
  47. </body>
  48. </html>
  • 浏览器结果:

  • 小结: {{ }}里填要渲染的变量,规范写法,两边用括号隔开 如 {{ 变量 }}, 后端没有传参的页面不显示

点(.)在模板语言中有特殊的含义,用来获取对象的相应属性值。

  • 例子 代码 .索引 .key .属性 .方法
  1. #views 文件函数
  2. def template_test(request):
  3. lis = [1, 2, 3,4,5]
  4. dic = {"name": "黑蛋"}
  5. class Person(object):
  6. def __init__(self, name, age):
  7. self.name = name
  8. self.age = age
  9. def dream(self):
  10. return " 我 is {} age {}岁...".format(self.name,self.age)
  11. gangdan = Person(name="钢蛋", age=18)
  12. goudan = Person(name="狗蛋", age=17)
  13. tiedan = Person(name="铁蛋", age=16)
  14. person_list = [gangdan, goudan, tiedan]
  15. return render(request, "template_test.html", {"lis": lis, "dic": dic, "person_list": person_list})
  16. # 模板文件html页面
  17. <!DOCTYPE html>
  18. <html lang="en">
  19. <head>
  20. <meta charset="UTF-8">
  21. <title>郭楷丰</title>
  22. </head>
  23. <boby>
  24. <p>{{ lis.0 }}</p> <!--取l中的第一个参数-->
  25. <p>{{ dic.name }}</p><!--取字典中key的值-->
  26. <p>{{ person_list.0.name }}</p><!--取对象的name属性-->
  27. <p>{{ person_list.0.dream }}</p><!--.操作只能调用不带参数的方法-->
  28. </boby>
  29. </html>
  • 小结:
  1. #注:当模板系统遇到一个(.)时,会按照如下的顺序去查询:
  2. 1. 在字典中查询
  3. 2. 属性或者方法
  4. 3. 数字索引 # 索引不能为负数

Tags 标签 {% %} 表示逻辑相关的操作

  • 代码例子
  1. {% for foo in lis %}
  2. <!--for循环-->
  3. {% if %}
  4. <!--if判断-->
  5. {% elif %}
  6. <!--elif判断-->
  7. {% endif %}
  8. <!--if闭合符-->
  9. {% else %}
  10. <!--else判断不成立执行-->
  11. {% endfor %}
  12. <!--for循环闭合符-->
  13. <!--应用 模板html代码-->
  14. <form action="" method="post">
  15. <label for="inputEmail3" class="col-sm-2 control-label">书名: </label>
  16. <div class="col-sm-8">
  17. <input type="text" name="book_name" class="form-control" value="{{ edit_obj.title }}">
  18. <select name="pub_id" id="" class="btn btn-default btn-sm">
  19. {% for foo in publishers %}
  20. {% if foo == edit_obj.pub %}
  21. <option selected value="{{ foo.pk }}"> {{ foo.name }}</option>
  22. {% else %}
  23. <option value="{{ foo.pk }}"> {{ foo.name }}</option>
  24. {% endif %}
  25. {% endfor %}
  26. </select>
  27. </div>
  28. <div class="text-center text-danger">{{ error }}</div>
  29. <div class="col-sm-offset-2 col-sm-10">
  30. <button type="submit" class="btn btn-default">提交</button>
  31. </div>
  32. </form>
  33. <!--应用 python逻辑代码 #views 文件函数-->
  34. def edit_book(request):
  35. error = ''
  36. pk = request.GET.get('pk')
  37. edit_obj = models.Book.objects.filter(id=pk)
  38. if not edit_obj:
  39. return HttpResponse('要编辑的数据不存在')
  40. if request.method == 'POST':
  41. book_name = request.POST.get('book_name')
  42. if not book_name.strip():
  43. error = "书名不能为空"
  44. pub_id = request.POST.get('pub_id')
  45. if edit_obj[0].title == book_name and edit_obj[0].pub_id == int(pub_id):
  46. error = "未作修改"
  47. if not error:
  48. obj = edit_obj[0]
  49. obj.title = book_name
  50. obj.pub_id = int(pub_id)
  51. obj.save()
  52. return redirect('/book_list/')
  53. publishers = models.Publisher.objects.all()
  54. return render(request,'edit_book.html',{'edit_obj':edit_obj[0],'publishers':publishers,'error':error})
  • 执行效果

  • if语句支持 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判断。

  • js,python,模板语言的判断逻辑

    1. #python
    2. 10>5>1 =》 10>5 and 5>1 true
    3. #js
    4. 10>5>1 =》 10>5 =》 true =》 1>1 false
    5. #模板中
    6. 不支持连续连续判断,也不支持算数运算(过滤器)
  • 注意事项

  • Django的模板语言不支持连续判断,也不支持以下写法:

  1. {% if a > b > c %}
  2. ...
  3. {% endif %}
  4. #不支持算数运算 + - * /
  • Django的模板语言中属性的优先级大于方法
  1. def xx(request):
  2. d = {"a": 1, "b": 2, "c": 3, "items": "100"}
  3. return render(request, "xx.html", {"data": d})
  • 如上,我们在使用render方法渲染一个页面的时候,传的字典d有一个key是items并且还有默认的 d.items() 方法,此时在模板语言中:
  1. {{ data.items }} 默认会取ditems key的值。

for循环可用的一些参数:

Variable Description
forloop.counter 当前循环的索引值(从1开始)
forloop.counter0 当前循环的索引值(从0开始)
forloop.revcounter 当前循环的倒序索引值(到1结束)
forloop.revcounter0 当前循环的倒序索引值(到0结束)
forloop.first 当前循环是不是第一次循环(布尔值)
forloop.last 当前循环是不是最后一次循环(布尔值)
forloop.parentloop 本层循环的外层循环

Filters 过滤器

  • 用来修改变量的显示结果, 语法: {{ value|filter_name:参数 }} ':' 左右没有空格没有空格没有空格

  • 设置除法除尽 divisibleby:参数

with 的使用

  • 定义一个中间变量(起个别名,只在with内部生效)
  1. #写法一
  2. {% with total=business.employees.count %}
  3. {{ total }} employee{{ total|pluralize }}
  4. {% endwith %}
  5. #写法二
  6. {% with business.employees.count as total %}
  7. {{ total }} employee{{ total|pluralize }}
  8. {% endwith %}

default 系统默认值

  1. {{ value|default:"nothing"}}
  2. 如果value值没传的话就显示nothing
  3. 注:TEMPLATESOPTIONS可以增加一个选项:string_if_invalid'找不到',可以替代default的的作用。
  4. (在配置文件settings.py设置)
  • 配置设置变量不传参显示值

  • 页面效果

filesizeformat 文件大小人性化显示

  • 将值格式化为一个 “人类可读的” 文件尺寸 (例如 '13 KB', '4.1 MB', '102 bytes', 等等)例如:
  1. {{ value|filesizeformat }}
  2. 如果 value 123456789,输出将会是 117.7 MB

add "加"

  • 给变量加参数,字符串默认尝试转int类型,转不了就拼接
  1. {{ value|add:"2" }}
  2. value是数字4,则输出结果为6
  3. {{ value|add:"hello" }}
  4. value是数字666,则输出结果为666hello
  5. {{ first|add:second }}
  6. 如果first [1,.2,3] second [4,5,6] ,那输出结果是 [1,2,3,4,5,6]

lower 小写

  1. {{ value|lower }}

upper 大写

  1. {{ value|upper}}

title 标题

  1. {{ value|title }}

ljust 左对齐

  1. "{{ value|ljust:"10" }}"

rjust 右对齐

  1. "{{ value|rjust:"10" }}"

center 居中

  1. "{{ value|center:"15" }}"

length 长度

  1. {{ value|length }}
  2. 返回value的长度,如 value=['a', 'b', 'c', 'd']的话,就显示4.

slice 切片

  1. {{value|slice:"2:-1"}}

first 取第一个元素

  1. {{ value|first }}

last 取最后一个元素

  1. {{ value|last }}

join 使用字符串拼接列表

  • 同python的str.join(list)
  1. {{ value|join:" // " }}

truncatechars 按照字符截断 ...也计数

  • 如果字符串字符多于指定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列(“...”)结尾
  1. #参数:截断的字符数
  2. {{ value|truncatechars:9}}
  3. truncatewords 按照单词进行截断, 只针对英文

date 日期格式化

  1. #后端
  2. import datetime
  3. def mul(request):
  4. value = datetime.datetime.now()
  5. return render(request, 'mul.html',{'value':value})
  6. #模板语句
  7. {{ value|date:"Y-m-d H:i:s"}} #显示格式 年-月-日 时:分:秒
  8. #后端
  9. import datetime
  10. def mul(request):
  11. now = datetime.datetime.now()
  12. return render(request, 'mul.html',{'now':now})
  13. #模板直接使用变量
  14. {{ now }} #显示格式 June 19,2019,22:00 p.m.
  • 页面效果

  • 可格式化输出的字符: 点击查看
  • 改配置文件设置显示样式 (一劳永逸的解决办法)
  1. #settings.py文件设置
  2. USE_L10N = False #更换为False
  3. DATETIME_FORMAT = 'Y-m-d H:i:s' #添加
  4. #也可以日期与时间分开设置 根据自己的需求设置
  5. DATE_FORMAT = 'Y-m-d'
  6. TIME_FORMAT = 'H:i:s'

safe 防止xss攻击 作用 取消转义

  • 简单了解xss攻击
  1. XSS攻击全称跨站脚本攻击,是为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,
  2. 故将跨站脚本攻击缩写为XSSXSS是一种在web应用中的计算机安全漏洞,它允许恶意web用户将代码植入到提供给其它用户使用的页面中。
  3. XSS是一种经常出现在web应用中的计算机安全漏洞,它允许恶意web用户将代码植入到提供给其它用户使用的页面中。
  4. 比如这些代码包括HTML代码和客户端脚本。攻击者利用XSS漏洞旁路掉访问控制——例如同源策略(same origin policy)。
  5. 这种类型的漏洞由于被骇客用来编写危害性更大的网络钓鱼(Phishing)攻击而变得广为人知。对于跨站脚本攻击,
  6. 骇客界共识是:跨站脚本攻击是新型的“缓冲区溢出攻击“,而JavaScript是新型的“ShellCode”。
  • xss攻击流程

safe 主要作用

  1. #Django的模板中会对HTML标签和JS等语法标签进行自动转义,原因显而易见,这样是为了安全。
  2. 但是有的时候我们可能不希望这些HTML元素被转义,比如我们做一个内容管理系统,后台添加的文章中是经过修饰的,
  3. 这些修饰可能是通过一个类似于FCKeditor编辑加注了HTML修饰符的文本,如果自动转义的话显示的就是保护HTML标签的源文件。
  4. 为了在Django中关闭HTML的自动转义有两种方式,如果是一个单独的变量我们可以通过过滤器“|safe”的方式告诉Django这段代码是安全的不必转义。
  • 正常情况下
  1. #页面代码:
  2. {% load my_tags %}
  3. {{ 'https://www.baidu.com/'|show:'百度' }}
  4. #自定过滤器代码
  5. @register.filter
  6. def show(url,name):
  7. return "<a href = '{}'>{}</a>".format(url,name)
  • 页面显示效果

  • 过滤器函数 加is_safe = True 解除转义
  1. #自定过滤器代码
  2. @register.filter(is_safe = True)
  3. def show(url,name):
  4. return "<a href = '{}'>{}</a>".format(url,name)
  • 页面效果

  • 模板语句中加 safe 解除转义

  1. #模板语句
  2. {% load my_tags %}
  3. {{ 'https://www.baidu.com/'|show:'百度'|safe }}
  • 页面效果

  • 也可以导入模块实现这种效果

自定义 filter

  • 当普通的内置过滤器,实现不了我们的开发需求,那我们可以自定义过滤器来实现功能
  1. 自定义过滤器是只能带有一个或两个参数的Python函数:
  2. 变量(输入)的值 - -不一定是一个字符串
  3. 参数的值 - 这可以有一个默认值,或完全省略
  4. 例如,在过滤器{{var | foo:“bar”}}中,过滤器foo将传递变量var和参数“bar”。
  5. 自定义filter代码文件摆放位置:
  6. app01/
  7. __init__.py
  8. models.py
  9. templatetags/ # 在app01下面新建一个package package
  10. __init__.py
  11. app01_filters.py # 建一个存放自定义filter的py文件
  12. views.py

自定义过滤器流程

  • 1 在app下创建一个名为templatetags的python包
  1. #注意
  2. settings中的INSTALLED_APPS配置当前app,不然django无法找到自定义的simple_tag
  3. (模块名只能是templatetags)
  • 2 在python中创建py文件,文件名可以自定义 如:(my_tags.py)

  • 3 在py文件中写:

  1. from django import template
  2. register = template.Library() #固定写法,不可改变
  • 4 写函数+装饰器
  1. @register.filter #过滤器
  2. def add_str(value, arg): # 最多有两个
  3. return '{}-{}'.format(value, arg)
  • 5 写页面代码 在使用自定义simple_tag和filter的html文件中导入之前创建的 my_tags.py
  1. {% load my_tags %} #先导入我们自定义那个文件 my_tags
  2. {{ name|add_str:age }} #参数只能是两个,一个参数是变量name ,一个是参数是后面的那个参数age
  • 执行结果

  • 自定义乘法过滤器 multioly

  1. #过滤器函数
  2. @register.filter
  3. def multiply1(value,arg):
  4. return value * arg
  5. #模板语句
  6. {% load my_tags %}
  7. <p>{{ 6|multiply1:'6' }}</p>
  8. <p>{{ 6|multiply1:6 }}</p>
  9. <p>{{ '10'|multiply1:5 }}</p>
  • 执行结果

  • 自定义除法过滤器 division

  1. #过滤器函数
  2. @register.filter
  3. def division(value,arg):
  4. return value / arg
  5. #模板语句
  6. {% load my_tags %}
  7. <p>{{ 6|division:6 }}</p>
  8. <p>{{ 6|division:1 }}</p>
  • 执行结果

  • 自定义除法过滤器 add

  1. #过滤器函数
  2. @register.filter
  3. def add(value,arg):
  4. return value + arg #可以这样写,但是转换不了会报错 int(value) + int(arg)
  5. #模板语句
  6. {% load my_tags %}
  7. <p>{{ 6|add:6 }}</p>
  8. <p>{{ 6|add:0 }}</p>
  9. <p>{{ '钢蛋g'|add:18 }}</p>
  • 执行结果

  • 自定义减法过滤器 subtraction

  1. #过滤器函数
  2. @register.filter
  3. def add(value,arg):
  4. return value - arg
  5. #模板语句
  6. {% load my_tags %}
  7. <p>{{ 6|add:6 }}</p>
  8. <p>{{ 6|add:0 }}</p>
  • 执行结果

自定义标签 simpletag

  • 与自定义过滤器区别,可以接受更多参数,使用标签引用{{% %}
  1. 与自定义filter类似(也是在python包的templatetags文件下,创建此标签),只不过接收更灵活的参数。
  2. #simple_tag 代码
  3. @register.simple_tag(name="plus")
  4. def plus(a, b, c):
  5. return "{} + {} + {}".format(a, b, c)
  6. #使用simple tag 自定义标签
  7. {% load app01_demo %}
  8. {# simple tag #}
  9. {% plus "1" "2" "abc" %}
  10. #例子 标签代码
  11. @register.simple_tag
  12. def join_str(*args, **kwargs):
  13. return '{} - {} '.format('*'.join(args), '$'.join(kwargs.values()))
  14. # 模板
  15. {% load my_tags %}
  16. {% join_str '1' '2' '钢蛋' k1='3' k2='4' %}
  • 执行效果

自定义标签 inclusion_tag

  • 多用于返回html代码片段 (动态变量 分页)

  • app文件下 创建python包

  • 包文件名必须为 templatetags

  • 在templatetags里面创建任意 .py 文件

  • 写函数

  • html页面代码

    1. #分页显示代码
    2. <nav aria-label="Page navigation">
    3. <ul class="pagination">
    4. <li>
    5. <a href="#" aria-label="Previous">
    6. <span aria-hidden="true">&laquo;</span>
    7. </a>
    8. </li>
    9. {% for i in num %}
    10. <li><a href="#">{{ i }}</a></li>
    11. {% endfor %}
    12. <li>
    13. <a href="#" aria-label="Next">
    14. <span aria-hidden="true">&raquo;</span>
    15. </a>
    16. </li>
    17. </ul>
    18. </nav>
    19. #页面1
    20. {% load my_tags %}
    21. {% page 5 %}
    22. #页面2
    23. {% load my_tags %}
    24. {% page 1 %}
  • 显示效果

  • 总结:

  1. 自定义过滤器 filter 只能接受两个参数 调用的时候使用 {{ filter }}
  2. 自定义标签 simpletag 与自定义过滤器区别,可以接受更多参数,使用标签引用{{% %}
  3. 自定义标签 inclusion_tag 多用于返回html代码片段,使用标签引用{{% %}

csrf_token 跨站请求伪造保护

  1. 在页面的form表单里面写上{% csrf_token %}
  • 如图

静态文件相关

  1. #作用 在配置文件找到静态文件别名,与文件地址进行拼接,这样别名改了,也不会影响,静态文件的导入
  2. {% load static %}
  3. <img src="{% static "images/hi.jpg" %}" alt="Hi!" />
  4. #引用JS文件时使用:
  5. {% load static %}
  6. <script src="{% static "mytest.js" %}"></script>
  7. #某个文件多处被用到可以存为一个变量
  8. {% load static %}
  9. {% static "images/hi.jpg" as myphoto %}
  10. <img src="{{ myphoto }}"></img>
  11. {% load static %}
  12. <link rel="stylesheet" href="{% static '/plugins/bootstrap-3.3.7/css/bootstrap.css' %}">
  13. <link rel="stylesheet" href="{% static '/css/dsb.css' %}">
  14. {% static '/plugins/bootstrap-3.3.7/css/bootstrap.css' %}
  15. {% get_static_prefix %} # 获取别名
  • 获取配置文件的 别名

母版和继承

什么是母版?

  1. 普通的HTML页面 母版页用于处理html页面相同部分内容,避免出现冗余代码,减少重复html页面的编写,提高代码复用性,方便代码修改.

继承写法

  1. #在子页面中在页面最上方使用下面的语法来继承母板。
  2. {% extends '母版文件名.html' %}

block 块

  1. 通过在母板中使用{% block xxx %}来定义"块"
  2. 在子页面中通过定义母板中的block名来对应替换母板中相应的内容。
  3. #定义block
  4. {{% block 块名 %}}
  5. {{% endblock %}}

子页面替换母版 block块

  • 注意事项
  1. 注意的点:
  2. 1. {% extends 'base.html' %} 写在第一行 前面不要有内容 有内容会显示
  3. 2. {% extends 'base.html' %} 'base.html' 加上引号 不然当做变量去查找
  4. 3. 把要显示的内容写在block块中
  5. 4. 定义多个block块,定义 css js

组件

  1. #作用
  2. 可以将常用的页面内容如导航条,页尾信息等组件保存在单独的文件中,然后在需要使用的地方按如下语法导入即可。
  3. #示列 单独建一个html page
  4. <nav aria-label="Page navigation">
  5. <ul class="pagination">
  6. <li>
  7. <a href="#" aria-label="Previous">
  8. <span aria-hidden="true">&laquo;</span>
  9. </a>
  10. </li>
  11. {% for i in num %}
  12. <li><a href="#">{{ i }}</a></li>
  13. {% endfor %}
  14. <li>
  15. <a href="#" aria-label="Next">
  16. <span aria-hidden="true">&raquo;</span>
  17. </a>
  18. </li>
  19. </ul>
  20. </nav>
  21. #别的页面 引用
  22. {% include 'page.html' %}

原文链接:http://www.cnblogs.com/guokaifeng/p/11060280.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号