经过前面的过程,这个博客的基本功能框架已经差不多了,下面主要本着用户体验的原则增加一些方便使用的小功能。这一节就来实现归档、标签分类、aboutme和分页这四个功能。
归档
归档就是列出当前博客里面的所有已发表文章,并且能够显示发布时间。
首先,在base.html里面增加一个归档按钮,位置参照其他按钮:
归档
然后,在mysite\mysite\urls.py添加一条url:
url(r'^archives/$', views.archives, name='archives'),
接着,在views.py增加一个视图逻辑:
from django.http import Http404
def archives(request):
try:
post_list = Article.objects.all().filter(published_date__isnull=False).order_by('-published_date')
except Article.DoesNotExist:
raise Http404
return render(request, 'blog/archives.html', {'post_list': post_list, 'error': False})
最后,在mysite\templates\blog增加一个模板archives.html:
{% extends "blog/base.html" %}
{% block content %}
{% for post in post_list %}
-
{{ post.published_date |date:'M d, Y'}}
{{ post.title }}
{% endfor %}
{% endblock %}
标签分类
标签分类就是点击对应的标签按钮, 会跳转到一个新的页面,这个页面是所有相关标签的文章的罗列。
回顾一下,有标签的地方包括主页面和详情页面。因此第一步就是在这两个地方的标签设置链接,把下面:
{{ post.category }}
改成下面:
{% if post.category %}
{{ post.category|title }}
{% endif %}
这里还使用了if的原因是为了防止有的文章没有标签会出错。
第二步就是在mysite\mysite\urls.py添加一条url:
url(r'^tag(?P\w+)/$', views.search_tag, name='search_tag'),
第三条是增加视图:
def search_tag(request, tag):
try:
post_list = Article.objects.filter(category__iexact=tag).filter(published_date__isnull=False).order_by('-published_date')
except Article.DoesNotExist:
raise Http404
return render(request, 'blog/tag.html', {'post_list' : post_list})
第四步是增加模板tag.html:
{% extends "blog/base.html" %}
{% block content %}
{% for post in post_list %}
{{ post.published_date |date:'M d, Y'}}
{{ post.title }}
{{ post.text|linebreaks }}
{% endfor %}
{% endblock %}
AboutMe
这个就更没什么技术含量了。
base.html里再加一个按钮,现在按钮区域变成这样了:
增加urls.py:
url(r'^aboutme/$', views.about_me, name='about_me'),
增加视图views.py:
def about_me(request):
return render(request, 'blog/aboutme.html')
增加模板aboutme.html:
{% extends "blog/base.html" %}
{% block content %}
About Me 正在建设中...
{% endblock %}
这里面就完全发挥个人风格了。
分页
在首页显示文章列表时候需要分页显示,这时候可以使用django内置的Paginator来分页。官方文档:Pagination
只需要修改两处。
第一处,在views.py里面修改post_list逻辑:
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.db.models import Count
from .commons import cache_manager
def post_list(request):
postsAll = Article.objects.annotate(num_comment=Count('id')).filter(
published_date__isnull=False).order_by('-published_date')
for p in postsAll:
p.click = cache_manager.get_click(p)
paginator = Paginator(postsAll, 10) # Show 10 contacts per page
page = request.GET.get('page')
try:
posts = paginator.page(page)
except PageNotAnInteger:
# If page is not an integer, deliver first page.
posts = paginator.page(1)
except EmptyPage:
# If page is out of range (e.g. 9999), deliver last page of results.
posts = paginator.page(paginator.num_pages)
return render(request, 'blog/post_list.html', {'posts': posts, 'page': True})
第二处,修改post_list.html页面,增加分页div:
{% extends 'blog/base.html' %}
{% block content %}
{% for post in posts %}
... # post循环不变 # ...
{% endfor %}
{% if page %}
{% endif %}
{% endblock %}
这里设定每页显示十篇文章,也可以在视图里面修改成其他数量。
这里的分页间的切换只有上一页/下一页以及知道共有多少页,还不能实现任意页切换,因此还是不完善的。因为现在文章还不多,所以只用上一页/下一页切换还没有带来多少不便,等到文章数量多的时候就会有很大不便了。等有空或到时候再修改吧!
11.5 update:
实现分页的任意页切换。
在post_list.html里面修改分页的部分为:
{% if page %}
{% if posts.has_previous %}
上一页
{% endif %}
{% for page_number in posts.paginator.page_range %}
{% ifequal page_number posts.number %}
{{ page_number }}
{% else %}
{{ page_number }}
{% endifequal %}
{% endfor %}
{% if posts.has_next %}
下一页
{% endif %}
{% endif %}
2016.10.24