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)显示返回的帖

得到结果如下:

原文地址:https://www.cnblogs.com/zhanghongfeng/p/8543365.html

时间: 2024-08-28 13:25:46

Django之博客系统:自定义模板标签的相关文章

Django开发博客系统(01-前言与需求分析)

原本是跟着视频学,无奈发现视频中用到的资源找不到,于是自己买了本书来进行学习,贴上JD链接.<Django企业开发实战> 我的开发环境是win10+python3.8+django3.0.4,而书上是在linux环境下进行开发的,= =(汗),先这样学下去吧,毕竟面向百度编程.写博客也是为了督促一下自己,毕竟在家里宅着容易学着学着就玩手机去了.. 书前面还有一些入门知识,这里我就直接跳到做项目的部分了. 目标是开发一个博客系统, 需求分析: 简单来说,博客分为两个部分:读者访问部分(用户端)和

django 搭建博客系统之创建博客的数据库模型

在我们之前已经创建好了虚拟环境,以及开始一个项目. 现在我们要添加一些功能性代码,django鼓励我们把自己编写的代码放入app中,每个app实现一个功能. 如今新建一个blog app 1,在虚拟环境下进入根目录,运行 python manage.py startapp blog.就建立了一个名为blog的应用,app. 2,在setting.py 中'告诉'django 存在这样的一个app. 好了 我们已经有了blog这个app,是要实现博客文章,博客的文章应该含有标题.正文.作者.发表时

Django开发博客系统(04-常用字段与属性)

Django models中常用的字段类型 数值型 这些类型都是数值相关的. l  AutoField int(11). 自增主键,Django Model默认提供,可以被重写.完整定义是 id = models.AutoField(primary_key=True) l  BooleanFueld tinyint(1). 布尔类型字段,一般用于记录状态标记. l  DecimalField decimal. 开发对数据精度要求高的业务时考虑使用,比如做支付相关,金融相关.定义时需要指定精确到多

Django开发博客系统(08-路由配置与views编写)

我们需要的页面: l  博客首页 l  博文详情页 l  分类列表页 l  标签列表页 l  友链展示页 但实际上,博客首页,分类列表页和标签列表页,本质上都是文章列表页,只有一些信息有差别.那么View大概就有三类: l  列表页: 根据不同的查询条件分别展示博客首页,分类列表页和标签列表页 l  博文详情页: 展示博文详情页 l  友链展示页: 展示所有友情链接 书上使用的环境是django1.11.1,而我使用的是3.0.4,所以路由我使用path来写,并且把路由分散开来写,让代码分工能明

Django开发博客系统(07-根据需求定制管理后台)

运行系统尝试添加用户并添加数据,出现的效果 可以看到当前登录的用户虽然是DOCTOR,但依然可以看到其他用户的文章,而且过滤器上也展示了非当前用户创建的分类,显然这是一个需要我们解决的问题. 首先解决右侧过滤器的功能,这时需要自定义过滤器,这里贴上文档中的说明 接下来我们就来编写自定义过滤器的代码: 1 class CategoryOwnerFilter(admin.SimpleListFilter): 2 """自定义过滤器只展示当前用户分类""&quo

Django开发博客系统(11-使用xadmin)

这段时间进行了前端页面的美化,实现了搜索功能与评论功能,以及配置了rss和sitemap,不过这些东西后期可能还会进行大改,所以暂时不准备讲,可能完成之后会一起说一下...吧. 另外这里贴上我的源码,不过还没有完成,有兴趣可以去看看. 今天将后台的admin替换为了xadmin,xadmin是国人创建的一个开源项目,作者github,这个项目简单来说可以完全无痛地替换admin,同时增加很多有用的功能,界面也是基于Bootstrap,相较自带的更美观. 先来看看最终完成的效果图吧 接下来就进行x

Django开发博客系统(05-QuerySet的使用)

在Model层中,Django通过objects属性来提供数据操作的接口, 比如我们想要查询所有文章的数据,只需要 Post.objects.all() 他会返回一个QuerySet对象,当我们需要用到它时,它会去db中获取数据,注意是用到的时候才会去查,而不是定义的时候去查,原因是QuerySet要支持链式操作,如果每次执行都要查询数据库的话,会影响性能,假设我要查询所有文章中状态为正常的文章,有如下代码. posts = Post.objects.all() available_posts

Django 自定义模板标签和过滤器

1.创建一个模板库 使用模板过滤器的时候,直接把过滤器写在app里,例如:在app里新建一个templatetags的文件夹,这个目录应当和 models.py . views.py 等处于同一层次.例如: books/     __init__.py     models.py     templatetags/     views.py 在 templatetags 中创建两个空文件:一个 __init__.py (告诉Python这是一个包含了Python代码的包)和一个用来存放你自定义的

django “如何”系列4:如何编写自定义模板标签和过滤器

django的模板系统自带了一系列的内建标签和过滤器,一般情况下可以满足你的要求,如果觉得需更精准的模板标签或者过滤器,你可以自己编写模板标签和过滤器,然后使用{% load %}标签使用他们. 代码布局 自定义标签和过滤器必须依赖于一个django app,也就是说,自定义标签和过滤器是绑定app的.该app应该包含一个templatetags目录,这个目录一个和model.py,views.py在同一个层级,记得在该目录下建立一个__init__.py文件一遍django知道这是一个pyth