Django之博客系统:自定义模板标签
Django提供了很多内置的模板标签比如{% if %}或者{% block %}Django也允许你创建自己的模板标签(template tags)来执行自定义的动作。当你需要在你的模板中添加功能而Django模板标签(template tags)的核心设置无法提供此功能的时候,自定义模板标签会非常方便
Django提供了以下帮助函数(functions)来允许你以一种简单的方式创建自己的模板标签(template tags):
- simple_tag:处理数据并返回一个字符串(string)
- inclusion_tag:处理数据并返回一个渲染过的模板(template)
- assignment_tag:处理数据并在上下文(context)中设置一个变量(variable
进入你的blog应用目录,创建一个新的目录命名为templatetags的包接着在该目录下继续创建一个文件并命名为blog_tags.py。到此,我们的blog应用文件结构应该如下所示:
我们将要开始创建一个简单标签(simple tag)来获取blog中所有已发布的帖子。编辑你刚才创建的blog_tags.py文件,加入以下代码
from ..models import Post
from django.db.models import Count
@register.simple_tag
def total_posts():
count=0
posts = Post.objects.all()
for p in posts:
if p.status == "published":
count+=1
return count
我们已经创建了一个简单的模板标签(template tag)用来取回目前为止所有已发布的帖子。每一个模板标签(template tags)都需要包含一个叫做register的变量来表明自己是一个有效的标签(tag)库。这个变量是template.Library的一个实例,它是用来注册你自己的模板标签(template tags)和过滤器(filter)的。我们用一个Python函数定义了一个名为total_posts的标签,并用@register.simple-tag装饰器定义此函数为一个简单标签(tag)并注册它如果你想使用别的名字来注册这个标签(tag),你可以指定装饰器的name属性,比如@register.simple_tag(name='my_tag')
现在我们已经定义好了标签,接下来就是要在模板中使用这些标签。使用的方法是采用load的方式,我们新建一个测试的html网页(test.html):
{% load blog_tags %}
{% load staticfiles %}
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}{% endblock %}</title>
<link href="{% static "css/blog.css" %}" rel="stylesheet">
</head>
<body>
<div id="content">
{% block content %}
{% endblock %}
</div>
<div id="sidebar">
<h2>我的博客</h2>
<p>这是我的博客,到目前为止我已经写了 {% total_posts %} 篇博客.</p>
</div>
在网页中,首先{% load blog_tags %}加载了blog_tags这个标签,blog_tags就是我们新建的blog_tags.py的文件名。{% total_posts %}就是我们在blog_tags中定义的函数,这里直接取用该函数的返回的值
运行服务器,并输入http://127.0.0.1:8000/test/。在页面中显示如下。
通过这种自定义标签的模式我们可以看到,模板内容的显示使得我们不用去关心视图函数,我们可以在模板中运行查询集或者处理任何数据展示结果。
inclusion_tags:
前面simple_tags返回的是一个字符串。在inclusion_tags将会看到如何返回一个模板进行渲染。在blog_tags.py中新增如下函数。
@register.inclusion_tag('post/latest_post.html')
def show_latest_post(count=2):
posts = Post.objects.all()
latest_post=posts.filter(status="published").order_by('-publish')[:count]
return {'latest_post':latest_post}
在以上代码中,我们通过装饰器@register.inclusion_tag注册模板标签(template tag),指定模板(template)必须被post/latest_posts.html返回的值渲染。我们的模板标签(template tag)将会接受一个可选的count参数(默认是2)允许我们指定我们想要显示的帖子数量。这个函数返回了一个字典变量而不是一个简单的值。包含标签(inclusion tags)必须返回一个字典值,作为上下文(context)来渲染特定的模板(template)。包含标签(inclusion tags)返回一个字典
另外在函数中的参数count在这里我们默认的是2,那么这个参数是否可以更改呢。答案是可以的。参数的传入需要在模板中进行。下面来看下模板的定义
首先创建一个新的模板latest_post.html。在这个模板中通过对传入的latest_post的遍历来显示所有的博客名称
<ul>
{% for post in latest_post %}
<li>
<a>{{ post.title }}</a>
</li>
{% endfor %}
</ul>
然后在test.html中新增如下代码:
<h3>最新的博客</h3>
{% show_latest_post 2 %}
在这里引用了show_latest_post模板,并在这里传入了参数2,这个参数也将传入给show_latest_post函数。
现在重启服务器并运行,注意:如果新增或者更新了标签函数需要重启服务器才能生效。
运行效果如下
assignment_tag:
分配标签(assignment tag)类似简单标签(simple tags)但是他们将结果存储在给予的变量中。我们将会创建一个分配标签(assignment tag)来展示拥有最多评论的帖子。编辑blog_tags.py文件,在其中添加如下导入和模板标签:
@register.assignment_tag
def get_most_commented_posts(count=2):
posts=Post.objects.all()
return posts.filter(status="published").annotate(total_comments=Count("comments")).order这个查询集(QuerySet)使用annotate()函数,为了进行聚合查询,使用了Count聚合函数。我们构建了一个查询集(QuerySet),聚合了每一个帖子的评论总数并保存在total_comments字段中,接着我们通过这个字段对查询集(QuerySet)进行排序。我们还提供了一个可选的count变量,通过给定的值来限制返回的帖子数量。_by('total_comments')[:count]
编辑test.html文件,添加如下代码:
{% get_most_commented_posts as most_commented_posts %}
<ul>
{% for post in most_commented_posts %}
<li>
<a>{{ post.title }}</a>
</li>
{% endfor %}
</ul>
使用分配模板标签(assignment template tags)的方法是{% template_tag as variable %}。对于我们的模板标签(template tag)来说,我们使用{% get_most_commented_posts as most_commented_posts %}。 这样,我们可以存储这个模板标签(template tag)返回的结果到一个新的名为most_commented_posts变量中。之后,我们就可以用一个无序列表(unordered list)显示返回的帖
得到结果如下:
Django之博客系统:自定义模板标签的更多相关文章
- Django之博客系统:增加标签
一般在发表博客后会给每个帖子加上一个标签.类似帖子关键字的功能.在这一章中来看下如何给博客添加标签功能(tagging) 添加标签需要集成第三方的Django标签应用来完成这个功能.django-ta ...
- django 简易博客开发 2 模板和数据查询
首先还是贴一下项目地址 https://github.com/goodspeedcheng/sblog 因为代码全在上面 上一篇博客我们介绍了 django的安装配置,新建project,新建a ...
- Django练习——博客系统小试
在上一篇博客Todolist的基础上(http://blog.csdn.net/hcx25909/article/details/24251427),本周继续进行实践,这次我要搭建一个简单的博客系统. ...
- 纯django开发博客系统
企业级教程:纯django开发博客系统 1.视频教程 https://www.duanshuilu.com/ 2.教程文档 https://www.duanshuilu.com/ 0.课程简介1.简价 ...
- Django(博客系统):基于pycharm如何一个django工程下创建多个app
背景:通常我们创建一个django系统时,为了把业务模块划分清楚往往会把一个独立的业务模块放到一个app中,如果多个独立的业务模块就会创建多个app,一般情况下为了更好的管理这些app,会把他们都存放 ...
- Django之博客系统搭建一
前面已经介绍了django的各种用法,从这一章开始,将实际搭建一个blog系统. 首先我们需要设计blog的模型,在models.py中添加如下内容 # -*- coding: utf-8 -*- f ...
- 【django之博客系统开发】
一.项目简介 使用django开发一套博客系统,参考博客园. 需求如下: 项目结构: 二.全部代码 from django.db import models # Create your models ...
- Django之博客系统邮件分享博客
在上一章中,我们创建了一个基础的博客应用,我们能在http://127.0.0.1:8000/blog/显示我们的博客.在这一章我们将尝试给博客系统添加一些高级的特性,比如通过email来分享帖子,添 ...
- Django之博客系统:增加评论
3既然是博客,那肯定就有留言评论系统.在这一章就来建立一个评论系统. 1 创建一个模型来保存评论 2 创建一个表单来提交评论并且验证输入的数据 3 添加一个视图函数来处理表单和保存新的评论到数据库 4 ...
随机推荐
- 机器学习:SVM(SVM 思想解决回归问题)
一.SVM 思想在解决回归问题上的体现 回归问题的本质:找到一条直线或者曲线,最大程度的拟合数据点: 怎么定义拟合,是不同回归算法的关键差异: 线性回归定义拟合方式:让所有数据点到直线的 MSE 的值 ...
- 2016.7.27 VS搜索正则表达式,在UltraEdit中可选用Perl正则引擎,按C#语法搜索
表达式 语法 说明 任一字符 . 匹配除换行符外的任何一个字符. 最多 0 项或更多 * 匹配前面表达式的 0 个或更多搜索项. 最多一项或更多 + 匹配前面表达式的至少一个搜索项. 最少 0 项或更 ...
- 第七章 Java中的13个原子操作类
当程序更新一个变量时,如果多线程同时更新这个变量,可能得到期望之外的值,比如变量i = 1:A线程更新i + 1,B线程也更新i + 1,经过两个线程操作之后可能i不等于3,而是等于2,.因为A和B线 ...
- NodeJS之Url的使用
一.通过http模块中的request事件可以得到在服务端拿到客户端的有关url的数据(req.url),其中req.url得到的数据是端口号后的所有路径,之后通过调入url模块对获取到的req.ur ...
- linux环境下Apache+Tomcat集群配置
写在前面 apache配置多个tomcat,实现请求分流,多个tomcat服务均衡负载,增加服务的可靠性.最近研究了一下,遇到许多问题,记录一下,方便以后查阅,不喜欢apache,nginx也是可以做 ...
- DAY17-认证系统
COOKIE 与 SESSION 概念 cookie不属于http协议范围,由于http协议无法保持状态,但实际情况,我们却又需要“保持状态”,因此cookie就是在这样一个场景下诞生. cookie ...
- Yahoo浮沉录
Yahoo这一路曾经出过很多好技术 然而,任何人如果只是把 Yahoo 当作一家缺乏聚焦的企业来看也许忽视了公司内部的那些创新—偶尔甚至还有一些很好的产品创意.就拿搜索来说吧,我们说的不是付费搜索,而 ...
- jquery datatable设置垂直滚动后,表头(th)错位问题
jquery datatable设置垂直滚动后,表头(th)错位问题 问题描述: 我在datatable里设置:"scrollY": '300px',垂直滚动属性后,表头的宽度就会 ...
- day17 13.滚动结果集介绍
滚动 一般结果集只能是向下的,不是滚动的,你要是想让它滚动你得设置才行. 类名或者接口里面有静态的可以.接口里面的属性全部都是public static final,类名/接口名.是属性,这些都是常量 ...
- html标签的显示模式(块级标签,行内标签,行内块标签)(转)
html标签的显示模式(块级标签,行内标签,行内块标签) 今天讲课的时候,讲到了html中的标签的显示模式,大致分为块级标签和行内标签.那么初学者在刚使用标签的时候会发现有些属性在一些标签上不起作 ...