BBS项目侧边栏&自定义分页器

侧边栏和注册页面使用了inclusion_tag,自定义分页器使用了模版导入include

此外,因为有一个普通的注册界面和一个模态框实现的注册页面,因此也注册也使用了inclusion_tag(这里不再介绍,感兴趣参考Github上BBS仓库的完整源码)

侧边栏

BBS项目个人站点左侧侧边栏用于展示文章标签、文章分类、日期归档的统计信息。

个人站点主页需要上述展示,文章详情页面也需要侧边栏的这些展示信息。

另外,侧边栏的统计信息的数据来自数据库动态展示,因此考虑使用inclusion_tag,将样式和数据绑定到一块,然后导入到前端个人站点模版文件blog_base.html

最后,个人站点blog.html和文章详情article_detail.html两个页面继承个人站点模版文件blog_base.html

inclusion_tag定义流程

应用中新建一个名字为 templatetags的文件夹
该文件夹内新建一个mytags.py的文件(文件名自定义)
在该文件内准备如下代码:
from django import template

register = template.Library()

代码

  • side_bar函数返回的数据给side_bar.html模板文件。
  • 然后在前端页面使用标签side_bar,则会将绑定了数据的side_bar.html当做局部放在前端页面上。

blog_base.html

{% load mytags %}
{% side_bar username %}		# 将username传给side_bar

mytags.py

from django import template
from django.db.models import Count
from django.db.models.functions import TruncMonth
from app01 import models

register = template.Library()


@register.inclusion_tag('side_bar.html', name='side_bar')
def side_bar(username):
    user_obj = models.UserInfo.objects.filter(username=username).first()
    blog = user_obj.blog
    # 标签、分类、归档ORM查询
    tag_list = models.Tag.objects.filter(blog=blog).annotate(c=Count('article__pk')).values('pk', 'name', 'c')
    category_list = models.Category.objects.filter(blog=blog).annotate(c=Count('article__pk')).values('pk', 'name', 'c')
    # 日期归档查询使用django提供的TruncMonth自动按月截取,形成一个虚拟字段用于日期分组
    archive_list = models.Article.objects.filter(blog=blog). \
        annotate(month=TruncMonth('publish_time')).values('month'). \
        annotate(c=Count('pk')).order_by('-month').values('month', 'c')

    return locals()

side_bar.html

<div class="panel panel-primary">
    <div class="panel-heading">
        <h3 class="panel-title">文章标签</h3>
    </div>
    <div class="panel-body">
        {% for tag in tag_list %}
            <p><a href="/{{ username }}/tag/{{ tag.pk }}/">{{ tag.name }}({{tag.c}})</a></p>
        {% endfor %}
    </div>
</div>
<div class="panel panel-success">
    <div class="panel-heading">
        <h3 class="panel-title">文章分类</h3>
    </div>
    <div class="panel-body">
        {% for category in category_list %}
            <p><a href="/{{username}}/category/{{ category.pk }}">{{ category.name }}({{category.c}})</a></p>
        {% endfor %}
    </div>
</div>
<div class="panel panel-info">
    <div class="panel-heading">
        <h3 class="panel-title">文章归档</h3>
    </div>
    <div class="panel-body">
        {% for archive in archive_list %}
            <p><a href="/{{ username }}/archive/{{ archive.month|date:'Y-m' }}/">{{ archive.month|date:'Y年m月' }}({{ archive.c }})</a></p>
        {% endfor %}
    </div>
</div>

自定义分页器

因为bbs主页和个人站点文章列表都需要使用分页,因此考虑使用模版继承的方式实现代码重用。

后端设置

  • CV自定义分页器代码,参考
  • 在视图函数中设置(bbs主页视图、文章详情视图两个位置设置方式类似)
# bbs首页的视图函数
def index(request):
    article_queryset = models.Article.objects.all()

    current_page = request.GET.get('page', 1)
    all_count = article_queryset.count()
    # 1 传值实例化对象
    page_obj = Pagination(current_page=current_page, all_count=all_count)
    # 2 直接对总数据进行切片操作
    page_queryset = article_queryset[page_obj.start:page_obj.end]
    # 3 将page_queryset传递到页面,替换之前的book_queryset

    return render(request, 'index.html', locals())

前端模版文件设置

  • bbs首页继承跟base.html模版文件,并通过模版导入的方式引入局部分页器模版文件mypagination.html
# index.html
{% extends 'base.html' %}

{% block left_content %}
   '''侧边栏代码略'''
{% endblock %}

{% block right_content %}
    <div class="col-md-9">
        '''文章列表代码略'''

        {#分页器#}
        {% include 'mypagination.html' %}
    </div>
{% endblock %}
  • mypagination.html内直接模版语法,并借助内置过滤器safe将自定义分页器渲染到前端页面。
# mypagination.html
<div class="text-center">
    {{ page_obj.page_html|safe }}
</div>
posted @ 2020-06-14 20:05  the3times  阅读(151)  评论(0编辑  收藏  举报