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一樣添加