Django搭建我的博客:統計文章瀏覽量

文章瀏覽量是全部社交類網站所必備的數據,足以顯示其重要性了。html

博主能夠經過瀏覽量來評估某篇文章的受歡迎程度,讀者也可以經過瀏覽量來篩選質量更高的文章。前端

然而,準確統計瀏覽量並不簡單:python

  • 某些類型的請求不該該統計爲瀏覽量,好比做者本身的瀏覽或編輯文章以後的重定向請求;
  • 因爲用戶衆多,瀏覽量的數據時刻都在快速更新,會給數據庫帶來很大的壓力。所以不少大型網站都會使用如Redis這樣的讀寫速度很是快的內存數據庫輔助存儲。

由於咱們的項目是博客網站,粗略統計就能夠了,也沒有那麼大的用戶壓力,因此設計就簡單得多了。git

模型

瀏覽量做爲每篇博文都有的數據,須要一個字段來存儲。github

所以修改文章的模型:redis

article/models.py

...
class ArticlePost(models.Model):
    ...
    
    total_views = models.PositiveIntegerField(default=0)
    
    ...
  • PositiveIntegerField是用於存儲正整數的字段
  • default=0設定初始值從0開始

修改完數據庫別忘了要數據遷移,不然更改不會生效。數據庫

因爲新字段設置了初始值,遷移會很順暢:django

(env) E:\django_project\my_blog>python manage.py makemigrations
Migrations for 'article':
  article\migrations\0003_articlepost_total_views.py
    - Add field total_views to articlepost
Migrations for 'userprofile':
  userprofile\migrations\0002_auto_20181227_2041.py
    - Alter field avatar on profile
    - Alter field user on profile

(env) E:\django_project\my_blog>python manage.py migrate
Operations to perform:
  Apply all migrations: admin, article, auth, contenttypes, sessions, userprofile
Running migrations:
  Applying article.0003_articlepost_total_views... OK
  Applying userprofile.0002_auto_20181227_2041... OK

列表模板

爲了方便觀察效果,此次先寫模板文件。後端

什麼地方須要顯示瀏覽量呢?很容易想到的就是文章列表了。修改文章列表的模板:bash

templates/article/list.html

...

<div class="card-footer">
    <!-- 已有代碼 -->
    <a href="{% url 'article:article_detail' article.id %}"
        class="btn btn-primary">
        閱讀本文
    </a>

    <!-- 顯示瀏覽量 -->
    <span>
        <small class="col align-self-end" style="color: gray;">
            瀏覽: {{ article.total_views }}
        </small>
    </span>

</div>

...

筆者將瀏覽量顯示在了「閱讀本文」的邊上。

有的同窗以爲顯示在這裏很差看,請修改代碼,將其放到本身最滿意的地方。(順便熟悉一下Bootstrap!)

詳情模板

除了文章列表外,一般詳情頁面中也須要顯示瀏覽量。

除此以外,在前面的學習中爲了方便,沒有作任何權限管理,以致於任何用戶均可以對全部文章進行修改、刪除:

這樣是確定不行的,必須修復這個嚴重的錯誤。

修改article/detail.html模板文件:

templates/article/detail.html

...
<!-- 文章詳情 -->
<div class="container">
    <div class="row">
        ...
        <div class="col-12 alert alert-success">
            <div>
                做者:{{ article.author }}
                {% if user == article.author %}
                    · <a href="#" onclick="confirm_delete()">刪除文章</a>
                    · <a href="{% url "article:article_update" article.id %}">
                        編輯文章
                    </a>
                {% endif %}
            </div>
            <div>
                瀏覽:{{ article.total_views }}
            </div>
        </div>
        ...
</div>
...

修改內容有:

  • 確認當前登陸用戶是文章的做者,才顯示「刪除文章、「編輯文章」兩個連接
  • 顯示瀏覽量

修改後的頁面以下:

上圖中因爲文章做者和登陸用戶不一致,修改文章的連接沒有渲染出來了;若是登陸用戶是做者本人,它們又會正常顯示。

這樣的方法能夠阻止大部分的「好用戶」非法修改數據。可是若是有「壞用戶」直接輸入url地址來使壞,該怎麼辦呢?因此光是靠前端頁面來鑑權是不夠的。

視圖

如今瀏覽量可以正確顯示了,可是因爲沒有進行任何處理,其數值會一直爲0。咱們但願每當用戶訪問詳情頁面時,瀏覽量就加1。

修改article_detail()以下:

article/views.py

...
def article_detail(request, id):
    article = ArticlePost.objects.get(id=id)
    
    # 瀏覽量 +1
    article.total_views += 1
    article.save(update_fields=['total_views'])
    
    ...

update_fields=[]指定了數據庫只更新total_views字段,優化執行效率。

測試一下,能夠正常對瀏覽量計數了:

視圖中鑑權

前面講了,光是在模板中鑑權是不夠的,必須在後端業務邏輯中再次驗證用戶身份。

修改article_update()更新文章的視圖:

article/views.py

...
# 提醒用戶登陸
@login_required(login_url='/userprofile/login/')
def article_update(request, id):
    # 已有代碼
    article = ArticlePost.objects.get(id=id)

    # 過濾非做者的用戶
    if request.user != article.author:
        return HttpResponse("抱歉,你無權修改這篇文章。")

    ...

視圖中進行了兩次鑑權:

  • login_required裝飾器過濾未登陸的用戶
  • if語句過濾已登陸、但非做者本人的用戶

經過在業務邏輯中再次驗證身份,徹底阻止惡意用戶從中使壞了。

除了更新文章的視圖外,刪除文章也應該作相似的工做,請讀者自行修改並測試。

總結

本章完成了簡單的統計瀏覽量的功能,而且在先後端中對用戶的身份進行了驗證。

下一章學習與瀏覽量緊密相關的功能:查詢最熱文章

轉載請註明出處。
相關文章
相關標籤/搜索