base.html
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>{{ blog.title }}</title> <meta name="viewport" content="width=device-width, initial-scale=1"> {% load static %} <link rel="stylesheet" href="{% static 'bootstrap/css/bootstrap.min.css' %}"> <link rel="stylesheet" href="{% static 'fontAwesome/css/font-awesome.min.css' %}"> <link rel="stylesheet" href="{% static 'sweetalert/sweetalert.css' %}"> <link rel="stylesheet" href="/static/publice.css"> <link rel="stylesheet" href="/static/theme/{{ blog.theme }}"> </head> <body> <div class="header"> <p>{{ blog.title }}</p> </div> <div class="container" style="width: 90%"> <div class="row"> <div class="col-md-3"> {# 下面这两行会帮我们自动的生成下面注释的部分#} {# 自定义过滤器#} {% load my_tags %} {% get_left_menu username %} </div> <div class="col-md-8"> {% block page_main %} {% endblock %} </div> </div> </div> <script src="{% static 'jquery-3.2.1.min.js' %}"></script> <script src="{% static 'setupajax.js' %}"></script> <script src="{% static 'bootstrap/js/bootstrap.min.js' %}"></script> <script src="{% static 'sweetalert/sweetalert.min.js' %}"></script> <script src="{% static 'gt.js' %}"></script> </body> </html>
article_detail.html
{% extends 'base.html' %} {% block page_main %} <div class="article-detail"> <h1>{{ article.title }}</h1> <p>{{ article.articledetail.content|safe }}</p> </div> {# 点赞和踩灭#} <div id="div_digg"> <div class="diggit"> <span class="diggnum" id="digg_count">{{ article.up_count }}</span> </div> <div class="buryit"> <span class="burynum" id="bury_count">{{ article.down_count }}</span> </div> <div class="clear"></div> </div> {% endblock %}
首先介绍一下{% load my_tags %} {% get_left_menu username %}
在开发中,如果遇到视图与数据相结合作为模板的时候,可以使用inclusion_tag(xxx)
,它接受一个参数,这个参数是你需要渲染的html代码。步骤大概如下:
-
在项目中创建一个名为templatetags的包(名字必须是这个)
-
在templatetags的包中创建存放自定义标签的py文件
my_tags.py
from django import template from app01 import models from django.db.models import Count register = template.Library() #就是一个自定义过滤器 #将下面函数的返回值返回到 left_menu.html 页面 @register.inclusion_tag("left_menu.html") def get_left_menu(username): user = models.UserInfo.objects.filter(username=username).first() blog = user.blog #查文章分类及对应的文章数 category_list = models.Category.objects.filter(blog=blog).annotate(c=Count("article")).values("title", "c") # 查文章标签及对应的文章数 tag_list = models.Tag.objects.filter(blog=blog).annotate(c=Count("article")).values("title", "c") # 按日期归档 目前我的好像不能执行,找不到 date_format archive_list = models.Article.objects.filter(user=user).extra( select={"archive_ym": "date_format(create_time,'%%Y-%%m')"} ).values("archive_ym").annotate(c=Count("nid")).values("archive_ym", "c")
return { 'category_list':category_list, 'tag_list':tag_list, 'archive_list':archive_list, }
left_menu.html
<div class="panel-heading">文章分类</div> <div class="panel panel-primary"> <div class="panel-body"> {% for category in category_list %} {# 分类名称和分类中的文章数#} {# <p>{{ category.title }}({{ category.article_set.all.count }})</p>#} <p>{{ category.title }}({{ category.c }})</p> {% endfor %} </div> </div> <div class="panel panel-primary"> <div class="panel-heading">文章标签</div> <div class="panel-body"> {% for tag in tag_list %} <p>{{ tag.title }}({{ tag.c }})</p> {% endfor %} </div> </div> {# <div class="panel panel-primary">#} {# <div class="panel-heading">日期归档</div>#} {# <div class="panel-body">#} {# {% for archive in archive_list %}#} {# <p>{{ archive.archive_ym }}({{ archive.c }})</p>#} {# {% endfor %}#} {# </div>#} {# </div>#}
app01的urls.py
from django.urls import path,re_path from app01 import views urlpatterns = [ re_path('(\w+)/article/(\d+)/$',views.article_detail), #文章详情 #这一行不能放在上面,要不然,他可以匹配所以,其余的就匹配不到了 re_path('(\w+)',views.home), #home(request,username) ]
它的顺序是:
- 在自定义的标签中,首先会执行代码,将数据传递给
inclusion_tag(xxx)
参数中的html,即get_left_menu.html - get_left_menu.html根据传来的数据完成自身的渲染
- base.html中调用
inclusion_tag
标签的部分完成渲染,即添加get_left_menu.html内容 - 个人站点页面继承模板页面,最终呈现