實戰Django:Rango Part6

 

24.優化模板 html


在這個項目中,從已經作過的模板來看,你可能會注意到裏面有不少重複的代碼。這種重複不只帶來大量無謂的工做量,並且之後調整起來也極爲不便。python

所以,最理想的作法是將那些重複的代碼放到基礎模板中,而後從基礎模板再擴展出一個個新的模板。chrome

咱們先來作這個基礎模板,在templates文件夾下新建一個base.html文件,而後添加如下內容:django

templates/base.html瀏覽器

<!DOCTYPE html>

<html>
    <head>
        <title>Rango - {% block title %}實戰Django!{% endblock %}</title>
    </head>

    <body>
        <div>
            {% block body_block %}{% endblock %}
        </div>

        <hr />

        <div>
            <ul>
            {% if user.is_authenticated %}
                <li><a href="/rango/restricted/">限制頁面</a></li>
                <li><a href="/rango/logout/">註銷</a></li>
                <li><a href="/rango/add_category/">新建分類</a></li>
            {% else %}
                <li><a href="/rango/register/">註冊</a></li>
                <li><a href="/rango/login/">登陸</a></li>
            {% endif %}

                <li><a href="/rango/about/">關於</a></li>
            </ul>
        </div>
    </body>
</html>

 

咱們來修改一下category.html這個模板,把內容改爲下面這樣:安全

templates/rango/category.html服務器

{% extends 'base.html' %}

{% load staticfiles %}

{% block title %}` category_name `{% endblock %}

{% block body_block %}
    <h1>` category_name `</h1>
    {% if category %}
        {% if pages %}
        <ul>
                {% for page in pages %}
                <li><a href="` page`.`url `">` page`.`title `</a></li>
                {% endfor %}
                </ul>
        {% else %}
                <strong>當前分類下尚無可用頁面!</strong>
                {% endif %}

        {% if user.is_authenticated %}
                <a href="/rango/category/`category`.`slug`/add_page/">添加頁面</a>
                {% endif %}
        {% else %}
            指定的分類名稱 ` category_name ` 不存在!
    {% endif %}

{% endblock %}

注意,咱們在第一行中寫了一句」{% extends 'rango/base.html' %} 「,它表示本模板繼承了base.html這個模板,這樣咱們在這個模板中就只需專一添加」block title「和」body_block 「這兩塊就行!cookie

咱們能夠用一樣的方式對其它的模板進行處理。網絡

在基礎模板中,咱們還能夠直接引用url的名稱。好比「關於」頁面的連接,原來寫的是:「session

  • <a href="/rango/about/">關於
  • 」,咱們能夠改爲這樣:

    templates/rango/base.html

    <li><a href="{% url 'about' %}">關於</a></li>

    當程序看到「{% url …}」的時候,它會自動去urls.py文件中找相應的名稱(好比說」about」).這樣寫的好處是,之後當咱們要修改連接時,沒必要去逐個改動模板,而只要在urls.py中進行修改就能夠了!

    」關於「這個頁面的連接咱們還能夠這樣寫:

    <li><a href="{% url 'rango.views.about' %}">關於</a></li>

    這至關於告訴程序,到」rango」這個應用中,找一個叫」about」的視圖。不過我仍是更喜歡前面一種寫法。

    咱們能夠將base.html模板中的那些連接寫成這樣:

    templates/rango/base.html(更新</body>前面的最後一個<div>標籤裏的內容)

    <div>
            <ul>
        {% if user.is_authenticated %}
            <li><a href="{% url 'restricted' %}">限制頁面</a></li>
            <li><a href="{% url 'logout' %}">註銷</a></li>
            <li><a href="{% url 'add_category' %}">新建分類</a></li>
        {% else %}
            <li><a href="{% url 'register' %}">註冊</a></li>
            <li><a href="{% url 'login' %}">登陸</a></li>
        {% endif %}
    
        <li><a href="{% url 'about' %}">關於</a></li>
        </ul>
    </div>

    咱們再來看看首頁模板,在index.html中,咱們能夠用一樣的方式來改造。

    好比category的連接,咱們能夠寫成:

    templates/rango/index.html(找不到麼?用第一行代碼搜索一下!):

                    {% for category in categories %}
                    <!-- 下面這行給分類加入了超連接 -->
                    <li><a href="{% url 'category'  category.slug %}">` category`.`name `</a></li>
                    {% endfor %}

    你能夠嘗試將全部的連接都改寫過來,捨得建議你們一開始就養成這樣寫的習慣。

    25.Cookies(信息指紋)和Sessions(會話)


    Cookies和Sessions在當今的網絡應用程序中是極爲重要的。事實上在以前咱們講到登陸和註銷的模塊時,咱們已經用到了Cookies和Sessions,只不過沒告訴你罷了。如今咱們來看看Cookies和Sessions在其它方面的應用。

    先來段測試。找到rango/views.py,在index視圖的第一行插入以下代碼:

    rango/views.py

    request.session.set_test_cookie()

    而後找到register視圖,在第一行插入下面三行代碼:

    if request.session.test_cookie_worked():
            print (">>>> TEST COOKIE WORKED!")
            request.session.delete_test_cookie()

    加完上面這些代碼(注意縮進哦),在瀏覽器的地址欄中輸入:

    http://127.0.0.1:8000/rango/

    而後點擊」註冊「連接,你應該能夠在你的Django服務器控制檯(Dos命令提示符下,還記得執行」python manage.py runserver」的地方不?)下看到以下的字樣:

    >>>> TEST COOKIE WORKED!

    若是看不到,多是你的瀏覽器中禁用了Cookies。

    好了,剛纔只是一個測試,如今你能夠刪掉添加那幾行代碼,繼續往下看。

    咱們知道cookies已經能正常工做了,讓咱們來作一個很是簡單的站點訪問數統計。要實現這項功能,咱們須要作兩個cookies,一個用來記錄用戶訪問Rango的次數,另外一個則用來記錄用戶上一次訪問Rango的時間,第二個cookies能夠幫助咱們統計那些一天內頻繁訪問Rango的用戶,無論他一天訪問多少次,咱們只算他一次的訪問量。

    編輯rango/views.py,修改index視圖:

    rango/views.py

    def index(request):
    
        category_list = Category.objects.all()
        page_list = Page.objects.order_by('-views')[:5]
        context_dict = {'categories': category_list, 'pages': page_list}
    
        # 獲取站點的訪問量
        # 咱們用COOKIES.get()方法來獲取cookie中的訪問數據
        # 若是cookie存在,則把返回的數值轉成整數
        # 若是cookie不存在,則將visits值設定爲0
        visits = int(request.COOKIES.get('visits', '0'))
    
        reset_last_visit_time = False
    
        # cookie中有last_visit這個值嗎?
        if 'last_visit' in request.COOKIES:
            # 好滴,果真有這個值
            last_visit = request.COOKIES['last_visit']
            # 將這個值用python的datetime庫轉換爲特定的日期格式
            last_visit_time = datetime.strptime(last_visit[:-7], "%Y-%m-%d %H:%M:%S")
    
            # 若是從上次登陸到如今已經超過一天,則訪問數加1...
            if (datetime.now() - last_visit_time).days > 0:
                visits = visits + 1
                # ...將重置last_visit時間的信號設爲True,表示此值須要更新
                reset_last_visit_time = True
        else:
            # Cookie中沒有last_visit值, 也將重置last_visit時間的信號設爲True
            reset_last_visit_time = True
    
            context_dict['visits'] = visits
    
        # 先渲染出response對象,以便增長cookie信息
        response = render(request, 'rango/index.html', context_dict)
        if reset_last_visit_time:
            response.set_cookie('last_visit', datetime.now())
        response.set_cookie('visits', visits)
    
        # 將response對象返回給用戶,更新需更改的cookie值
        return response

    由於咱們這裏用到了Python的datetime庫,別忘了在文件頭部加入這樣一句:

    from datetime import datetime

    咱們來看一下效果,在谷歌瀏覽器(chrome)中輸入:http://127.0.0.1:8000/rango/,首頁出現了。

    若是想看到訪問數據,須要作如下幾步操做:

    • 在瀏覽器窗口空白處點擊右鍵,從彈出的快捷菜單中選擇「審查元素」;
    • 轉到下方的」Resources「選項卡;
    • 從左下方找到」Cookies「項中的」127.0.0.1「,這樣就能看到訪問數(visits)了;

    5_thumb

    若是visits數據爲0,不妨修改一下系統時間(改到明天便可),而後再刷新瀏覽器的頁面,你就能夠觀察到數據的變化了。

    上面這個例子的訪問數據是儲存在用戶的電腦上的,然而,更安全也更經常使用的作法是將會話信息儲存到服務器上。

    要使用基於cookie的會話,你須要檢查一下Rango的環境:

    • 保證settings.py中的MIDDLEWARE_CLASSES配置中有「django.contrib.sessions.middleware.SessionMiddleware」這一句;
    • 保證settings.py中的INSTALLED_APPS配置中有「django.contrib.sessions」這一句;

    若是你在前面一步步作下來,那麼這兩項都應該符合要求的。

    咱們再來編輯rango/views.py,修改index視圖:

    rango/views.py

    def index(request):
    
        category_list = Category.objects.order_by('-likes')[:5]
        page_list = Page.objects.order_by('-views')[:5]
    
        context_dict = {'categories': category_list, 'pages': page_list}
    
        visits = request.session.get('visits')
        if not visits:
            visits = 0
        reset_last_visit_time = False
    
        last_visit = request.session.get('last_visit')
        if last_visit:
            last_visit_time = datetime.strptime(last_visit[:-7], "%Y-%m-%d %H:%M:%S")
            if (datetime.now() - last_visit_time).seconds > 0:
                # ...訪問數加1...
                visits = visits + 1
                # ...發出更新last_visit值的信號
                reset_last_visit_time = True
        else:
            # last_visit值不存在,發出建立last_visit值的信號.
            reset_last_visit_time = True
    
        context_dict['visits'] = visits
        request.session['visits'] = visits
        if reset_last_visit_time:
            request.session['last_visit'] = str(datetime.now())
    
    
        response = render(request,'rango/index.html', context_dict)
    
        return response

     

    【未完待續】

    本文版權歸捨得學苑全部,歡迎轉載,轉載請註明做者和出處。謝謝!
    做者:捨得
    首發:捨得學苑@博客園

    相關文章
    相關標籤/搜索