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

    得到结果如下:

  • 相关阅读:
    转:马云邮件全文
    XIFF资料1
    代码还是请一个字母一个字母敲(如果您只想混口饭吃就不要读了本文只面向想成为hacker的程序员)
    一个本来很有希望的项目噶然而止,脑子一下子空了
    转:进京感受一个技术人职业发展心得
    java中定义接口
    两个大数相乘(纯C实现)
    [ios学习入门1]hello,word!
    两台电脑通信的连接过程
    谁说引用不可改变
  • 原文地址:https://www.cnblogs.com/zhanghongfeng/p/8543365.html
Copyright © 2020-2023  润新知