python学习第9天---django框架---模板详解

python学习第9天---django框架---模板详解


目录




内容

1、模板的功能

 &emps;模板用于生产html,控制页面展示的内容。模板文件不仅仅是html文件,模板文件包含2部分内容:

  • 静态内容:js、css、img等等静态资源
  • 动态内容:用于动态生成一些页面内容,通过模板语言

2、模板文件的使用

2.1、使用步骤

  通常是通过视图函数使用模板生成html内容返回给客户端,步骤如下:

  1. 加载模板文件:loader.get_template,获取模板文件内容,生成一个模板对象
  2. 定义模板上下文:Context,给模板文件传递数据
  3. 模板渲染产生html页面:render,用传递的数据替换模板文件中的响应变量,生成替换后的html文件。

2.2、示例

  接上面书籍管理系统,我们把书籍管理系统登录后书籍管理首页及视图函数,稍加修改。

  • 模板文件代码2.2-1:index.html

      <!DOCTYPE html>
      <html lang="en">
      <head>
      	<meta charset="UTF-8">
      	<title>Title</title>
      	<style>
      		.book {
      			width: 200px;
      			height: 100px;
      			margin: 0 auto;
      		}
    
      		li {
      			color: green;
      		}
      	</style>
    
    
      </head>
      <body>
      <div class="book">
      	<h3 style="color: orange">{{ title }}首页</h3>
      	<hr>
      	<a href="http://127.0.0.1:8000/book/book_list">{{ content }}</a>
    
      </div>
      </body>
      </html>
    
  • 视图函数代码2.2-2:index

      def index(request):
      # return HttpResponse('欢迎进入书籍管理系统')
      # 1、加载模板文件,生成模板对象
      temp = loader.get_template('book/index.html')
      # 2、定义模板上下文,给模板文件传递数据
      content = {'title': '书籍管理', 'content': '书籍列表'}
      context = Context(content)
      # 3、模板渲染,替换模板文件中响应变量,返回html内容
      res_html = temp.render(content, request)
      # 4、返回应答
      return HttpResponse(res_html)
    
  • 效果图示2.2-1:在这里插入图片描述

2.3、封装

  render函数其实已经帮我们封装好了,直接使用就好了。代码2.3-1:

	def index(request):
		# return HttpResponse('欢迎进入书籍管理系统')
		return render(request, 'book/index.html', {'title': '书籍管理', 'content': '书籍列表'})

结果与2.2相同,有兴趣的小伙伴可以自己去查看render源代码。

3、模板文件的加载顺序

  在这里插入图片描述

  1. 首先去配置的模板目录下面找模板文件

    • 当前配置目录:

        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',
        		],
        	},
        },
      

      ]

  2. 去INSTALL_APPS下面的每个应用中去找模板文件,前提是应用中必须有templates文件夹

    • INSTALL_APPS:

        INSTALLED_APPS = [
        	'django.contrib.admin',  # 有templates目录
        	'django.contrib.auth',  # 有templates目录
        	'django.contrib.contenttypes',
        	'django.contrib.sessions',
        	'django.contrib.messages',
        	'django.contrib.staticfiles',
        	'book',  # book应用
        	'login',  # 登录应用
      
        ]
      

4、模板语言

4.1、模板变量

  • 命名:由字母、数字和下划线组成,不能以下划线开头
  • 使用:{{ var_name }}
  • 示例代码:查看2.2-1代码

4.2、模板标签

4.2.1、 循环:

  • 模板示例:

      {% for book in book_list %}
      	代码块
      {% endfor %}
    

4.2.2、判断

  • 模板示例:

      {% if 判断条件 %}
      	...
      {% elif 判断条件 %}
      	...
      {% else %}
      	...
      {% endif %}
    

4.3、过滤器

过滤器用于对模板变量操作。

  • 格式:模板变量 | 过滤器: 参数

4.3.1、常用内置过滤器

  • date:改变日期的显示格式
  • length:求长度。字符串,元组,列表,字典。
  • default:设置模板变量的默认值。

详细参数可以参考官方文档,地址:https://docs.djangoproject.com/en/3.0/

4.3.2、自定义过滤器

  过滤器本身是python函数一种。我们在自定义python函数后,需要注册才能成为过滤器函数,并且前端页面加载后,才可以同内置过滤器一样使用。

  • 步骤:

    1. 在应用下创建目录templatetags目录

    2. templatetags目录下新建自定义过滤器文件filters.py(文件名非固定)

    3. 编辑文件filters.py

      • 代码4.3.2-1:

          # 自定义过滤器
          from django import template
        
          # 创建Library对象
          register = template.Library()  # register固定名称
        
        
          @register.filter(name='isEven')  # name可省略,默认过滤器名字为函数名
          def isEven(num):
          	"""判断一个数是否是偶数"""
          	return num % 2 == 0
        
    4. settings.py中注册

      • 代码:4.3.2-2:

          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',
          			],
          			'libraries': {
          				# 自定义过滤器
          				'filters': 'book.templatetags.filters'
          			},
          		},
        
          	},
          ]
        
    5. 前端文件加载过滤器文件filters.py

      • book_list_filter.html代码4.3.2-3:

          <!DOCTYPE html>
          <html lang="en">
          {% load filters %}
          <head>
          	<meta charset="UTF-8">
          	<title>图书管理系统</title>
          	<style>
          		.test {
          			width: 550px;
          			height: 100px;
          			margin: 0 auto;
          		}
        
          		li {
          			color: green;
          		}
          	</style>
          </head>
          <body>
          <div class="test">
          	<h3 style="color: orange">书籍管理首页</h3>
          	<hr/>
          	<table border="1">
          		<thead>
          		<tr>
          			<th>ID</th>
          			<th>书籍名称</th>
          			<th>出版时间</th>
          			<th>阅读量</th>
          			<th>评论量</th>
          			<th>是否在售</th>
          			<th>书籍简介</th>
          		</tr>
          		</thead>
          		<tbody>
          		{% for book in book_list %}
          		{% if book.id|isEven %}
          		<!--自定义过滤器 -->
          		<tr style="color: red">
          			<td>{{ book.id }}</td>
          			<td>{{ book.name}}</td>
          			<td>{{ book.publishing_date|date:"Y/m/d"}}</td>
          			<td>{{ book.reading_volume}}</td>
          			<td>{{ book.comment_volume}}</td>
          			{% if book.isDelete %}
          			<td>否</td>
          			{% else %}
          			<td>是</td>
          			{% endif %}
          			<td><a href="http://127.0.0.1:8000/book/book_list/{{ book.id}}">点击查看</a></td>
          		</tr>
          		{% else %}
          		<tr style="color: green">
          			<td>{{ book.id }}</td>
          			<td>{{ book.name}}</td>
          			<td>{{ book.publishing_date|date:"Y/m/d"}}</td>
          			<td>{{ book.reading_volume}}</td>
          			<td>{{ book.comment_volume}}</td>
          			{% if book.isDelete %}
          			<td>否</td>
          			{% else %}
          			<td>是</td>
          			{% endif %}
          			<td><a href="http://127.0.0.1:8000/book/book_list/{{ book.id}}">点击查看</a></td>
          		</tr>
          		{% endif %}
          		{% endfor %}
          		</tbody>
          	</table>
          	<a href="http://127.0.0.1:8000/book/index">返回</a>
        
          </div>
          </body>
          </html>
        
    6. 使用-同内置过滤器

  • 示例,根据书籍id的奇偶显示不同颜色。

    • 图示4.3.2-1:在这里插入图片描述

4.4、模板运算符

  • 关系运算符:<,>,==,!=,<=,>=
  • 逻辑运算符:and,or, not,in

tips:运算符前后要加空格,不然会报错

4.5、模板注释

  • 单行注释:{# #}

  • 多行注释:

      {% comment %}
      	...
      {% endcomment
    

4.5、综合示例

  根据书籍id,显示不同的颜色。id<=2时,显示红色;id<=4时,显示绿色;其他的显示蓝色。

  • 示例代码4.5-1:book_list_structure.html

      <!DOCTYPE html>
      <html lang="en">
      <head>
      	<meta charset="UTF-8">
      	<title>图书管理系统</title>
      	<style>
      		.test {
      			width: 550px;
      			height: 100px;
      			margin: 0 auto;
      		}
    
      		li {
      			color: green;
      		}
      	</style>
      </head>
      <body>
      <div class="test">
      	<h3 style="color: orange">书籍管理首页</h3>
      	<hr/>
      	<table border="1">
      		<thead>
      		<tr>
      			<th>ID</th>
      			<th>书籍名称</th>
      			<th>出版时间</th>
      			<th>阅读量</th>
      			<th>评论量</th>
      			<th>是否在售</th>
      			<th>书籍简介</th>
      		</tr>
      		</thead>
      		<tbody>
      		{% for book in book_list %}
      			{% if book.id <= 2 %}
      				<tr style="color: red">
      					<td>{{ book.id }}</td>
      					<td>{{ book.name}}</td>
      					<td>{{ book.publishing_date|date:"Y/m/d"}}</td>
      					<td>{{ book.reading_volume}}</td>
      					<td>{{ book.comment_volume}}</td>
      					{% if book.isDelete %}
      					<td>否</td>
      					{% else %}
      					<td>是</td>
      					{% endif %}
      					<td><a href="http://127.0.0.1:8000/book/book_list/{{ book.id}}">点击查看</a></td>
      				</tr>
      			{% elif book.id <= 4 %}
      				<tr style="color: green">
      					<td>{{ book.id }}</td>
      					<td>{{ book.name}}</td>
      					<td>{{ book.publishing_date|date:"Y/m/d"}}</td>
      					<td>{{ book.reading_volume}}</td>
      					<td>{{ book.comment_volume}}</td>
      					{% if book.isDelete %}
      					<td>否</td>
      					{% else %}
      					<td>是</td>
      					{% endif %}
      					<td><a href="http://127.0.0.1:8000/book/book_list/{{ book.id}}">点击查看</a></td>
      				</tr>
      			{% else %}
      				<tr style="color: blue">
      					<td>{{ book.id }}</td>
      					<td>{{ book.name}}</td>
      					<td>{{ book.publishing_date|date:"Y/m/d"}}</td>
      					<td>{{ book.reading_volume}}</td>
      					<td>{{ book.comment_volume}}</td>
      					{% if book.isDelete %}
      					<td>否</td>
      					{% else %}
      					<td>是</td>
      					{% endif %}
      					<td><a href="http://127.0.0.1:8000/book/book_list/{{ book.id}}">点击查看</a></td>
      				</tr>
      			{% endif %}
      		{% endfor %}
      		</tbody>
      	</table>
      	<a href="http://127.0.0.1:8000/book/index">返回</a>
    
      </div>
      </body>
      </html>
    
  • 视图函数代码4.5-2:

      def book_list_structure(request):
      	'''书籍列表展示'''
      	books = Book.objects.all()
      	return render(request, 'book/book_list_structure.html', {'book_list': books})
    
  • url: url(r’^book_list_structure$’, views.book_list_structure),

  • 效果图示4.5-1:在这里插入图片描述

6、模板继承

  通常网站都有一些通用的网页部分,比如头部导航和底部版权信息。如果,所有页面都写一遍,增加很多工作量。这里使用模板继承很方便。

  • 父模板:公用模板

    • 格式:

        # 相同内容
        ...
        # 不同内容
        {% block 块名1 %}
        	...
        {% endblock 块名1 %}
        {% block 块名2 %}
        	...
        {% endblock 块名2 %}
        ...
        ...
      
    • 解析:

      • 对于通用的内容,即为普通的html
      • 不同的内容包裹在block块内
      • 可以有多个block块
  • 子模板:继承子父模板

    • 格式

        {% extends 父模板 %}
        {% block 块名1 %}
        	...
        {% endblock 块名1 %}
        {% block 块名2 %}
        	...
        {% endblock 块名2 %}
      
    • 解析:

      • 子模板可以重新块中的内容,也可以使用父模板原有的内容
      • block.super为父模板块中内容
  • 示例:pass

7、html转义

  模板上下文中的html标记默认是会被转义的。常见对应关系表格7-1:

显示 说明 html编码 16进制编码
半方大的空白 &ensp; &#8194;
全方大的空白 &emsp; &#8195;
不断行的空白格 &nbsp; &#160;
< 小于 &lt; &#60;
> 大于 &gt; &#62;
& &符号 &amp; &#38;
" 双引号 &quot; &#34;
© 版权 &copy; &#169;
® 已注册商标 &reg; &#174;
商标(美国) \™ &#8482;
× 乘号 &times; &#215;
÷ 除号 &divide; &#247;
  • 关闭自动转义
    • 单行关闭:

        {{ 模板变量|safe}}
      
    • 多行关闭:

        {% autoescape off %}
        	...
        {% endautoescape %}
      

感兴趣的小伙伴可以自行搜索,这里不再详述。

后记

  本项目为参考某音python系列视频。上面为自己参考写的学习笔记,持续更新。欢迎交流,本人QQ:806797785

  1. 原视频地址:https://space.bilibili.com/277754748?spm_id_from=333.788.b_765f7570696e666f.1
  2. 笔记项目源代码地址:https://gitee.com/gaogzhen/python
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章