Django+Bootstrap+Mysql 搭建個人博客(三)


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

&nbsp;&nbsp;&nbsp;&nbsp;分類:
                    {% for category in entry.category.all %}
                        &nbsp;&nbsp;<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

 &nbsp;&nbsp;&nbsp;&nbsp;標簽:
                    {% for tag in entry.tags.all %}
                        &nbsp;&nbsp;<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一樣添加

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM