我的Django学习笔记(4)模版引用和模版继承、自定义过滤器

模版结构优化:
1、模版引用 include:
将一段公共性的代码写入一个HTML文件,在其他HTML文件中可以使用include标签来读取公共代码

	如果想要在子模版中添加参数(父模版中所需要的参数),则需要手动传递:
		{% include '.html' with var=value %}

	base.html中的代码:
		<!DOCTYPE html>
		<html lang="en">
		<head>
		    <meta charset="UTF-8">
		    <title>Title</title>
		</head>
		<body>
		    <p>Hello,{{ username }}</p>
		</body>
		</html>

	index.html中的代码:
		{% include 'base.html' with username='Mike' %}

	views.py中的代码:
		def index_handler(request):
			return render(request, 'indexbase.html')

2、模板继承 extend:
	Django模板引擎中最强大也是最复杂的部分是模板继承。
	模板继承使您可以构建基本的“骨架”模板,该模板包含站点的所有常见元素并定义子模板可以覆盖的块

	使用继承的一种常见方法是以下三个级别的方法:
		(1)创建一个base.html包含网站主要外观的模板。
		(2)base_SECTIONNAME.html为站点的每个“部分” 创建一个模板。
				例如base_news.html,base_sports.html。
			这些模板全部扩展base.html并包括特定于部分的样式/设计。
		(3)为每种类型的页面(例如新闻文章或博客条目)创建单独的模板。这些模板扩展了相应的节模板。

	使用继承的一些技巧:
		(1)如果在模板中使用,则{% extends %}必须是该模板中的第一个模板标记。
			否则模板继承将不起作用

		(2)子模板不必定义所有父块,仅在以后定义所需的块
			{% block 块的名字%}{% endblock %}

		(3)如果发现自己在多个模板中复制内容,则可能意味着您应该将该内容移至父模板中的

		(4)如果需要从父模板中获取块的内容,则可以使用{{ block.super }}来解决问题。如

		(5)使用模板标记语法在a外部创建的变量不能在块内部使用

			{% trans "Title" as title %}
			{% block content %}{{ title }}{% endblock %}

编写自定义模版过滤器
查看默认的DTL过滤器:
from django.templates import defaultfilters, defaulttags

(1)自定义过滤器只是采用一两个参数的Python函数(最多只能有两个)
(2)参数的值–可以具有默认值,也可以完全省略
(3)过滤器的第一个参数必须是value
(4)app文件下创建一个名为templatetags(必须是这个名字)的python包(含__init__.py文件)

由于模板语言不提供异常处理,因此从模板过滤器引发的任何异常都将作为服务器的错误公开发布

1、编写自定义过滤器
2、注册自定义过滤器
	使用方法:
		django.template.Library.filter()
		编写过滤器定义后,需要在Library实例中注册它,以使其可用于Django的模板语言
			Library.filter()有两个参数:
				一个是过滤器的名称–字符串。
				另一个是编译函数– Python函数
		也可以把register.filter()改为用作装饰器来注册过滤器
		register.filter()还接受三个关键字参数:is_safe,needs_autoescape,expects_localtime
3、在html中使用标签load加载自定义的过滤器

(以一个项目为例子,我们来实际操作一波)时间显示器,在评论区一般都有一个时间显示器,表明这条评论已经存在多久了
templates.templates.py中的代码:
	from django import template
	from datetime import datetime

	register = template.Library()


	def time_since(value, time=None):
	    if not isinstance(value, datetime):
	        return value
	    now = datetime.now()
	    timespace = (now - value).total_seconds()
	    if timespace < 60:
	        return "刚刚"
	    elif timespace < 3600:
	        minutes = int(timespace/60)
	        return "%s分钟前" % minutes
	    elif timespace < 3600*24:
	        hours = int(timespace / 3600)
	        return "%s小时前" % hours
	    elif timespace < 3600*24*30:
	        days = int(timespace/3600/24)
	        return "%s天前" % days
	    else:
	        return value.strftime("%Y-%m-%d %H:%M")


	register.filter('time_since', time_since)


views.py中的代码:
	from django.shortcuts import render
	from datetime import datetime


	def autospace_handler(request):
	    context = {
	        'time': datetime(year=2020, month=7, day=10, hour=20, minute=56)
	    }
	    return render(request, 'index.html', context=context)

index.html中的代码:
	{% load templatestags %}
	<!DOCTYPE html>
	<html lang="en">
	<head>
	    <meta charset="UTF-8">
	    <title>Title</title>
	</head>
	<body>
	    {{ time|time_since }}
	</body>
	</html>

过滤器和自动转义
在编写自定义过滤器时,可以在模板代码内传递两种类型的字符串:
原始字符串是本机Python字符串。
在输出时,如果自动转义有效,则将它们转义,否则将保持不变。
安全字符串是已标记为可以在输出时进一步转义的字符串。
任何必要的转义操作已经完成。
它们通常用于包含原始HTML的输出,这些原始HTML打算在客户端按原样解释。

	在内部,这些字符串的类型为 SafeText,下面提供了检测字符串是不是SafeText类型:
		from django.utils.safestring import SafeText
		if isinstance(value, SafeText):

考虑到过滤器如果不引入任何HTML不安全的字符(<,>, ',"或&),让Django为您处理所有自动转义处理
	那么只需要在注册过滤器功能时将is_safe标志设置为True:
		@register.filter(name='time_since', is_safe=True)

		标记过滤器is_safe会将过滤器的返回值强制为字符串。
		如果您的过滤器应返回布尔值或其他非字符串值,则标记它is_safe可能会产生意想不到的后果(例如将布尔False转换为字符串'False')。

该标志告诉Django,如果将 SafeText字符串传递到过滤器中,则结果仍将是 SafeText
如果传入了not SafeText字符串,则Django将在必要时自动对其进行转义。

is_safe=True是有必要的,因为有很多普通的字符串操作会将一个SafeData对象变成一个普通的str对象,而不是尝试全部捕获它们,可能会造成数据的丢失
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值