3.1.分页功能
(1)views.py
from django.core.paginator import Paginator,EmptyPage,PageNotAnInteger def make_paginator(objects, page, num=3):
paginator = Paginator(objects, num)
try:
object_list = paginator.page(page)
except PageNotAnInteger:
object_list = paginator.page(1)
except EmptyPage:
object_list = paginator.page(paginator.num_pages)
return object_list, paginator def pagination_data(paginator, page):
"""
用于自定义展示分页页码的方法
:param paginator: Paginator类的对象
:param page: 当前请求的页码
:return: 一个包含所有页码和符号的字典
"""
if paginator.num_pages == 1:
# 如果无法分页,也就是只有1页不到的内容,则无需显示分页导航条,不用任何分页导航条的数据,因此返回一个空的字典
return {}
# 当前页左边连续的页码号,初始值为空
left = [] # 当前页右边连续的页码号,初始值为空
right = [] # 标示第 1 页页码后是否需要显示省略号
left_has_more = False # 标示最后一页页码前是否需要显示省略号
right_has_more = False # 标示是否需要显示第 1 页的页码号。
# 因为如果当前页左边的连续页码号中已经含有第 1 页的页码号,此时就无需再显示第 1 页的页码号,
# 其它情况下第一页的页码是始终需要显示的。
# 初始值为 False
first = False # 标示是否需要显示最后一页的页码号。
# 需要此指示变量的理由和上面相同。
last = False # 获得用户当前请求的页码号
try:
page_number = int(page)
except ValueError:
page_number = 1
except:
page_number = 1 # 获得分页后的总页数
total_pages = paginator.num_pages # 获得整个分页页码列表,比如分了四页,那么就是 [1, 2, 3, 4]
page_range = paginator.page_range if page_number == 1:
# 如果用户请求的是第一页的数据,那么当前页左边的不需要数据,因此 left=[](已默认为空)。
# 此时只要获取当前页右边的连续页码号,
# 比如分页页码列表是 [1, 2, 3, 4],那么获取的就是 right = [2, 3]。
# 注意这里只获取了当前页码后连续两个页码,你可以更改这个数字以获取更多页码。
right = page_range[page_number:page_number + 4] # 如果最右边的页码号比最后一页的页码号减去 1 还要小,
# 说明最右边的页码号和最后一页的页码号之间还有其它页码,因此需要显示省略号,通过 right_has_more 来指示。
if right[-1] < total_pages - 1:
right_has_more = True # 如果最右边的页码号比最后一页的页码号小,说明当前页右边的连续页码号中不包含最后一页的页码
# 所以需要显示最后一页的页码号,通过 last 来指示
if right[-1] < total_pages:
last = True elif page_number == total_pages:
# 如果用户请求的是最后一页的数据,那么当前页右边就不需要数据,因此 right=[](已默认为空),
# 此时只要获取当前页左边的连续页码号。
# 比如分页页码列表是 [1, 2, 3, 4],那么获取的就是 left = [2, 3]
# 这里只获取了当前页码后连续两个页码,你可以更改这个数字以获取更多页码。
left = page_range[(page_number - 3) if (page_number - 3) > 0 else 0:page_number - 1] # 如果最左边的页码号比第 2 页页码号还大,
# 说明最左边的页码号和第 1 页的页码号之间还有其它页码,因此需要显示省略号,通过 left_has_more 来指示。
if left[0] > 2:
left_has_more = True # 如果最左边的页码号比第 1 页的页码号大,说明当前页左边的连续页码号中不包含第一页的页码,
# 所以需要显示第一页的页码号,通过 first 来指示
if left[0] > 1:
first = True
else:
# 用户请求的既不是最后一页,也不是第 1 页,则需要获取当前页左右两边的连续页码号,
# 这里只获取了当前页码前后连续两个页码,你可以更改这个数字以获取更多页码。
left = page_range[(page_number - 3) if (page_number - 3) > 0 else 0:page_number - 1]
right = page_range[page_number:page_number + 2] # 是否需要显示最后一页和最后一页前的省略号
if right[-1] < total_pages - 1:
right_has_more = True
if right[-1] < total_pages:
last = True # 是否需要显示第 1 页和第 1 页后的省略号
if left[0] > 2:
left_has_more = True
if left[0] > 1:
first = True data = {
'left': left,
'right': right,
'left_has_more': left_has_more,
'right_has_more': right_has_more,
'first': first,
'last': last,
}
return data def index(request):
entries = models.Entry.objects.all()
page = request.GET.get('page', 1)
entry_list, paginator = make_paginator(entries, page)
page_data = pagination_data(paginator, page) return render(request, 'blog/index.html', locals())
(2)index.html
<!--/.pagination-->
<div id="paginator" class="pull-right">
<ul class="pagination">
{% if entry_list.has_previous %}
<li><a href="?page={{ entry_list.previous_page_number }}"><i
class="glyphicon glyphicon-chevron-left"></i>前一页</a></li>
{% endif %} {% if first %}
<li><a href="?page=1">1</a></li>
{% endif %} {% if left %}
{% if left_has_more %}
<span>...</span>
{% endif %} {% for i in left %}
<li><a href="?page={{ i }}">{{ i }}</a></li>
{% endfor %}
{% endif %} <li class="active"><a href="?page={{ entry_list.number }}">{{ entry_list.number }}</a></li> {% if right %}
{% for i in right %}
<li><a href="?page={{ i }}">{{ i }}</a></li>
{% endfor %} {% if right_has_more %}
<span>...</span>
{% endif %}
{% endif %} {% if last %}
<li><a href="?page={{ entry_list.num_pages }}">{{ entry_list.num_pages }}</a></li>
{% endif %} {% if entry_list.has_next %}
<li><a href="?page={{ entry_list.next_page_number }}">下一页<i
class="glyphicon glyphicon-chevron-right"></i></a></li>
{% endif %}
</ul>
</div>
</div>
3.2.分类
(1)urls.py
url(r'^category/(?P<category_id>[0-9]+)/$', views.catagory,name='blog_category'),
(2)views.py
def catagory(request,category_id):
c = models.Category.objects.get(id=category_id)
entries = models.Entry.objects.filter(category=c)
page = request.GET.get('page',1)
entry_list, paginator = make_paginator(entries, page)
page_data = pagination_data(paginator, page) return render(request, 'blog/index.html', locals())
(3)detail.html
分类:
{% for category in entry.category.all %}
<a href="{% url 'blog:blog_category' category.id %}">{{ category.name }}</a>
{% endfor %}
3.3.标签
(1)urls.py
url(r'^tag/(?P<tag_id>[0-9]+)/$', views.tag,name='blog_tag'),
(2)views.py
def tag(request,tag_id):
t = models.Tag.objects.get(id=tag_id)
if t.name == "全部":
entries = models.Entry.objects.all()
else:
entries = models.Entry.objects.filter(tags=t)
page = request.GET.get('page', 1)
entry_list, paginator = make_paginator(entries, page)
page_data = pagination_data(paginator, page)
return render(request, 'blog/index.html', locals())
(3)detail.html
标签:
{% for tag in entry.tags.all %}
<a href="{% url 'blog:blog_tag' tag.id %}">{{ tag.name }}</a>
{% endfor %}
3.4.搜索功能
(1)urls.py
url(r'^search/$', views.search,name='blog_search'),
(2)views.py
def search(request):
keyword = request.GET.get('keyword',None)
if not keyword:
error_msg = "请输入关键字"
return render(request,'blog/index.html',locals())
entries = models.Entry.objects.filter(Q(title__icontains=keyword)
| Q(body__icontains=keyword)
| Q(abstract__icontains=keyword))
page = request.GET.get('page', 1)
entry_list, paginator = make_paginator(entries, page)
page_data = pagination_data(paginator, page)
return render(request, 'blog/index.html', locals())
(3)base.html
<form class="navbar-form navbar-left" action="{% url 'blog:blog_search' %}">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search" name="keyword">
</div>
<button type="submit" class="btn btn-default">搜索</button>
</form>
3.5.博客侧边栏
(1)blog/templatetags/blog_tags.py
from django import template
from ..models import Entry,Category,Tag register = template.Library() @register.simple_tag
def get_recent_entries(num=5):
return Entry.objects.all().order_by('-created_time')[:num] @register.simple_tag
def get_popular_entries(num=5):
return Entry.objects.all().order_by('-visiting')[:num]
(2)blog/right_side_bar.html
{% load blog_tags %} <div class="row">
<div class="widget">
<h3>最新博客</h3>
{% get_recent_entries as recent_entry_list %} {% for entry in recent_entry_list %}
<div>
<a href="{{ entry.get_absolute_url }}">{{ entry.title }}</a>
<div>{{ entry.author }} 发表于:{{ entry.created_time|date:"Y年m月d日" }}</div>
</div>
{% endfor %}
</div>
</div> <div class="row">
<div class="widget">
<h3>推荐博客</h3>
{% get_popular_entries as popular_entry_list %} {% for entry in popular_entry_list %}
<div>
<a href="{{ entry.get_absolute_url }}">{{ entry.title }}</a>
<span class="badge" style="color: white;background-color: darkgreen">{{ entry.visiting }}</span>
</div>
{% endfor %}
</div>
</div>
(3)index.html
添加进去
<div class="col-md-3">
{% include 'blog/right_site_bar.html' %}
</div>
(4)detail.html一样添加