把模板的过程、语法、标签、反向地址解析、过滤器、模板继承与HTML转义记下笔记

1、概述及demo

动态生成HTML

模板的设计实现业务逻辑(View)和显示内容(template)的分离

一个模板可以给多个视图去使用,模板所使用的语法称为DTL(Django Template Language)定义在django.template包

如果要调用模板,则需要如下步骤:

  1. 加载模板。通过loader的get_template方法指定一个模板
  2. 渲染模板。
    1.   指定一个上下文对象,RequestContext()
    2.   用模板的render()方法接收上下文对象。作为HttpResponse()的参数

demo示例的过程:创建工程 - 添加数据库 - 创建应用 -  添加模板路径 - 设置路由 - 编写urls.py - 编辑视图 - 添加模板

添加模板路径:修改settings.py配置,在TEMPLATES中修改DIRS。指定TEMPLATES的目录

TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},

添加模板:

booktest/views.py

from django.http import HttpResponse
from django.template import loader, RequestContext
def resp(request):
t1 = loader.get_template('booktest/resp.html')
context = RequestContext(request, {"text":"helloworld"})
return HttpResponse(t1.render(context))

templates/booktest/resp.html

<body>
{{text}}
</body>

实际上上面的代码通过会被封装到一个函数render()中,所以我们一般简写为

from django.shortcuts import render
from django.http import HttpResponse def resp(request):
context = {"text":"helloworld"}
return render(request, "booktest/resp.html", context)

2、模板语法

  • 变量。两个大括号括起来的 {{变量名}}
  • 标签。代码段 {% 代码块 %}
  • 过滤器。就是一个竖线(|)
  • 注释。{# 这里是注释 #}

变量

模板碰到变量的时候,计算这个变量的值,然后将结果输出

变量名有字母、数字、下划线组成。必须以字母或下划线开头

当模板引擎碰到圆点的时候,会按照如下的顺序进行查询:

  1. 字典。把圆点前面的内容理解为一个字典,圆点后面的内容理解为键
  2. 属性或方法查询。把圆点前面的内容理解为一个对象,圆点后面的内容理解为对象里面的属性或方法(访问方法不能加括号,方法也不能定义参数)
  3. 数字索引查询。把圆点前面的内容理解为列表或元组。圆点后面的内容理解为下标(下标只能为数字,不能为字符串)

比如访问{{book.id}},会按照如下顺序解析:

  1. 把book当做字典。访问book[‘id’],如果book字典中有id的键,则查询成功,并返回,如果没有id的键,或者甚至没有book字典,查询失败,往下
  2. 把book当做对象,把id当做属性或方法,尝试访问book.id或book.id()如果book对象中有id的属性或方法,则查询成功,调用并返回,否则往下
  3. 把book当做列表或元组,把id当做索引,访问book[id],如果访问成功,则输出,否则往下
  4. 把book.id作为空字符串’’来输出

3、引入模型

在models.py中定义类HeroInfo

booktest/models.py

from django.db import models

# Create your models here.
class BookInfo(models.Model):
btitle = models.CharField(max_length = 20)
bpub_date = models.DateTimeField(db_column = 'pub_date')
bread = models.IntegerField()
bcomment = models.IntegerField()
isDelete = models.BooleanField()
class Meta():
db_table = 'bookinfo' class HeroInfo(models.Model):
hname = models.CharField(max_length = 10)
hgender = models.BooleanField()
hcontent = models.CharField(max_length = 1000)
isDelete = models.BooleanField()
book = models.ForeignKey('BookInfo', on_delete = models.CASCADE)
def showname(self):
return self.hname

生成迁移,数据库中生成bookinfo和booktest_heroinfo的表

>>>python manage.py makemigrations
>>>python manage.py migrate

把book和hero的sql语句插入到数据库中

修改视图类  booktest/views.py

from django.shortcuts import render
from booktest.models import BookInfo, HeroInfo # Create your views here.
def index(request):
hero = HeroInfo.objects.get(pk=1)
context = {'hero': hero}
return render(request, 'booktest/index.html', context)

模型中,既可以访问属性,也可以访问方法(访问方法不能加括号)

booktest/index.html

<body>
{{hero.hname}}
{{hero.showname}}
</body>

4、使用标签

语法:{% 标签 %}。注意标签中写的是代码

作用:

  1. 在输出中创建文本
  2. 循环或条件判断等逻辑
  3. 加载外部信息

for标签

{% for ... in ... %}
{{ forloop.counter }} 表示当前是第几次循环
{% empty %}
列表是空或不存在的时候,执行这里
{% endfor %}

修改views.py    booktest/views.py

# Create your views here.
def index(request):
heroList = HeroInfo.objects.filter(isDelete=False)
context = {'heroList': heroList}
return render(request, 'booktest/index.html', context)

模板的代码中添加for标签 templates/booktest/index.html

<ul>
{% for hero in heroList %}
<li>{{ forloop.counter }}: {{hero.showname}}</li>
{% empty %}
<li>找不到</li>
{% endfor %}
</ul>

if标签

{% if ... %}
逻辑1
{% elif ... %}
逻辑2
{% else %}
逻辑3
{% endif %}

比如,想奇数行显示红色,偶数行显示蓝色

<ul>
{% for hero in heroList %} {% if forloop.counter|divisibleby:"2" %}
<li style="color:red">{{ forloop.counter }}: {{hero.showname}}</li>
{% else %}
<li style="color:blue">{{ forloop.counter }}: {{hero.showname}}</li>
{% endif %} {% empty %}
<li>找不到</li>
{% endfor %}
</ul>

4、反向地址解释

{% url name p1 p2 ... %}

先创建一个页面

路由: booktest/urls.py

urlpatterns = [
url('^$',views.index), # 路由到views.py中的index()函数
url('^(\d+)$',views.show),
]

视图: booktest/views.py

urlpatterns = [
url('^$',views.index), # 路由到views.py中的index()函数
url('^(\d+)$',views.show),
]

模板:templates/booktest/show.html

<body>
{{id}}
</body>

接下来考虑在index中,添加一个链接,点击后可以跳转到123。一般是这样写

<a href="/booktest/123">跳转</a>

但是万一路由被改变了

urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url('booktest1/', include('booktest.urls'))
]

此时,链接的地址就发生了改变。如果要随时去修改链接的地址,就有点麻烦了

因此考虑使用地址的反向解释:

正向:在浏览器中输入url后,用该url去匹配规则(URL_PATTERNS)

反向:根据URL规则,生成一个地址

首先,在urls的根中,使用namespace

django4/urls.py

urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url('booktest/', include('booktest.urls', namespace='booktest'))
]

在子urls中,添加name

booktest/urls.py

urlpatterns = [
url('^$',views.index), # 路由到views.py中的index()函数
url('^(\d+)$',views.show, name="show"),
]

在模板中使用反向地址解释

{% url name p1 p2 ... %}

其中,这里的name是指namspace:name

<a href="{% url 'booktest:show' 123 %}">跳转</a>

5、过滤器

# 语法:
{{ 变量|过滤器 }}
# 比如:
{{ name|lower }}
# 表示将变量name的值全部变成小写
# 竖线|可以理解为python中的圆点(.)
# 可以在if标签中,使用过滤器,并结合运算符一起使用
{% if name|length > 2 %} # 过滤器可以用来串联,构成过滤器链
name | lower | upper # 过滤器可以传递参数
list | join:”,” # 设置默认值的过滤器
value | default:”0” #设置日期
value | date:”YYYY-mm-dd”

常用的django过滤器参考:https://www.cnblogs.com/huangxm/p/6286144.html

6、模板继承

很多网站的头部(页头)、底部(页脚)都是一样的。

把多个页面通用的部分抽取出来,做成父模板。然后在子模板中继承父模板,再实现各自的差异。

相关的概念:

block标签。在父模板中预留区域,在子模板中进行填充

定义父模板base.html

{% block block_name %}
这里可以定义默认值。如果不定义默认值,表示默认值为空
{% endblock block_name %}

extends继承。写在子模板文件的第一行

定义子模板index.html

{% extends ‘base.html’ %}
{% block block_name %}
实际填充内容
{% endblock block_name %}

如下例子:

定义父模板

在templates/booktest目录下创建base.html

templates/booktest/base.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>标题</title>
{% block head %}
{% endblock head %}
</head>
<body>
<h1>页头:logo</h1>
<hr/>
{% block content %}
<h1>默认的内容</h1>
{% endblock content %}
<hr/>
<h1>页脚:联系我们</h1>
</body>
</html>

子模板

templates/booktest/index2.html

{% extends 'booktest/base.html' %}

路由和视图略写了。

如果要修改中间的内容:

可以在index2.html中添加

{% extends 'booktest/base.html' %}
{% block content %}
<h1>修改后的内容</h1>
{% endblock content %}

7、HTML转义

通过视图往模板输出带html标签的内容的时候

booktest/views.py

def htmlTest(request):
context = {'text1':'<h2>123</h2>'}
return render(request, 'booktest/htmlTest.html', context)

对应的模板捕获

templates/booktest/htmlTest.html

<body>
{{text1}}
</body>

其实这里是做了html的转义。当我们给一段html格式的字符串的时候,到了模板中会自动的转义成特殊字符。最终原封不动的输出

实际上它使用的就是escape过滤器进行自动转义,所以下面两句是一样的效果

{{text1}}
{{text1 | escape }}

当需要按照它指定的格式输出的时候,考虑使用safe过滤器,目的是关闭转义

{{text1 | safe }}

如果有一整块代码都需要转义,考虑使用autoescape,并通过设置on打开转义,设置off关闭转义

{% autoescape off %}
{{text1}}
{% endautoescape %}

如果是在模板代码中直接写html字符串

{{ text2 | default:'<h2>456</h2>' }}

则直接输出456,不需要转义

Django:模板template(一)的更多相关文章

  1. django模板(template)

    模板层(template) 你可能已经注意到我们在例子视图中返回文本的方式有点特别. 也就是说,HTML被直接硬编码在 Python代码之中. 1 2 3 4 def current_datetime ...

  2. [django]模板template原理

    django 中的render和render_to_response()和locals(): http://www.cnblogs.com/wangchaowei/p/6750512.html 什么是 ...

  3. Django——模板层(template)(模板语法、自定义模板过滤器及标签、模板继承)

    前言:当我们想在页面上给客户端返回一个当前时间,一些初学者可能会很自然的想到用占位符,字符串拼接来达到我们想要的效果,但是这样做会有一个问题,HTML被直接硬编码在 Python代码之中. 1 2 3 ...

  4. Django模板语言(Template)

    1.变量 变量相关用 { { } }   逻辑相关用{% %} 2.Filter过滤器 (1)default 如果一个变量是false或者为空,使用给定的默认值. 否则,使用变量的值.   {{ va ...

  5. django模板语言之Template

    当前端的一些数据需要后端传送过来并展示时,用到了django的模板语言,模板语言的作用就是,在后端把一些处理好的数据,通过模板语言所规定的格式,通过render渲染,放到前端页面固定的位置展示.这之间 ...

  6. Django之模板Template

    模板介绍 作为Web框架,Django提供了模板,可以很便利的动态生成HTML 模版系统致力于表达外观,而不是程序逻辑 模板的设计实现了业务逻辑(view)与显示内容(template)的分离,一个视 ...

  7. Django之模板(Template)

    Django模板系统 官方文档 每一个Web框架都需要一种很便利的方法用于动态生成HTML页面. 最常见的做法是使用模板. 模板包含所需HTML页面的静态部分,以及一些特殊的模版语法,用于将动态内容插 ...

  8. Django 模板系统(template)

    介绍 官方文档 常用模板语法 只需要记两种特殊符号: {{  }} 和  {% %} 变量相关的用{{}} 逻辑相关的用{%%} 变量 {{ 变量名 }} 变量名由字母数字和下划线组成. 点(.)在模 ...

  9. Django框架简介及模板Template,filter

    Django框架简介 MVC框架和MTV框架 MVC,全名是Model View Controller,是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model).视图(View) ...

  10. Django模板系统:Template

    一.模板常用语法 1.1 变量 符号:{{ }} 表示变量,在模板渲染的时候替换成值 使用方式:{{ 变量名 }}:变量名由字母数字和下划线组成 点(.)在模板语言中有特殊的含义,用来获取对象的相应属 ...

随机推荐

  1. Easyui datagrid 特殊处理,记录笔记

    1. 特殊的单元格样式 columns中 { field: , styler: function (value, row, index) { ') { return 'background-color ...

  2. JS放在博客里面运行

    <ol><li>测试的内容</li><li>测试的内容</li><li>测试的内容</li><li>测试 ...

  3. 测试覆盖率工具:EclEmma

    测试覆盖率工具:EclEmma 2016-08-26 目录 1 测试覆盖率实现技术2 EclEmma介绍3 EclEmma测试覆盖率指标4 EclEmma安装5 示例项目介绍  5.1 创建项目  5 ...

  4. php框架之odp(一)

    熟悉odp框架的使用已经快一个月了,今天总结一下.odp和yii都是成熟的常用的php框架,因为odp是公司内部开发的,且公司内部用odp的较多,所以我就从odp框架入手.仅仅纪录自己的学习体会 一. ...

  5. 在Java API设计中,面向接口编程的思想,以及接口和工厂的关系

    现在的java API的设计中,提倡面向接口的编程,即在API的设计中,参数的传递和返回建议使用接口,而不是具体的实现类,如一个方法的输入参数类型应该使用Map接口,而不是HashMap或Hashta ...

  6. easyui 自定义验证规则 验证用户是否已经存在 远程ajax验证

    easyui远程ajax验证 2014年09月30日 22:29:32 clj198606061111 阅读数:6130 标签: easyui 更多 个人分类: jqueryeasyui 版权声明:本 ...

  7. 转载 :配置ssh密钥认证自动登录

    原文地址 :https://segmentfault.com/a/1190000000481249 在客户端来看,SSH提供两种级别的安全验证.[摘自wikipedia] 第一种级别(基于密码的安全验 ...

  8. IP分片与重组详解

    大家对IP数据包头,应该不陌生吧 分片便是与图中圈出来的两个地址有关,本文也是将主要围绕他们展开. 那我们先来了解他们的概念. 标志一个三比特字段遵循与用于控制或识别片段.他们是(按顺序,从高分以低位 ...

  9. Java------------JVM(Java虚拟机)优化大全和案例实战

    JVM(Java虚拟机)优化大全和案例实战 堆内存设置 原理 JVM堆内存分为2块:Permanent Space 和 Heap Space. Permanent 即 持久代(Permanent Ge ...

  10. Python 中filter函数用法

    filter()和map一样,接收一个函数和一个序列.和map不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素 过滤出奇数: de ...