Django django-hitcount 實作觀看次數


建立時間: 2022年4月8日 14:27
更新時間: 2023年3月13日 21:12

說明

這次實作觀看次數重點在於防止一直重新整理增加次數,一般來說實作方向會是在資料庫新增欄位 views 並且每進入此頁就加一,但為了防止一直重新整理增加次數,需要檢查的細節很多,這次就決定直接使用 django-hitcount 插件來實作它,這個插件可以完成所需的功能,之後可以再考慮加上 Google Analytics

安裝

使用 pip 安裝模組

$ pip install django-hitcount

接下來在 settings.py 設定

settings.py

INSTALLED_APPS = [
    'hitcount'
]

Model

以下提供我的實作範例,更多功能可以參考它的 Github 文件

修改 model 加入 hitcount 欄位

models.py

from django.contrib.contenttypes.fields import GenericRelation
from django.db import models
from hitcount.models import HitCountMixin, HitCount


class MyModel(models.Model, HitCountMixin):
    # 這個是要教學用的
    description = models.CharField(max_length=200)
    show = models.BooleanField(default=True)
    # 用來記錄觀看次數
    hit_count_generic = GenericRelation(
        HitCount, object_id_field='object_pk',
        related_query_name='hit_count_generic_relation'
    )

View

接下來是 view,這裡要注意的是它是使用 DetailView
DetailView 是 Django 給一些常用的 view 用的
在此不詳細說明 DetailView,需要了解的可以參考 Django 文件

views.py

from .models import MyModel
from hitcount.views import HitCountDetailView


class MyDetailView(HitCountDetailView):
    # 是否計算點擊
    count_hit = True
    # 使用的模組,預設使用 all 查詢
    # 如果要自訂查詢,可以用 get_queryset(),此屬性即可刪除
    model = MyModel
    # 使用的樣板
    template_name = 'my_page.html'

    def get(self, request, *args, **kwargs):
        """找不到 model 重導向到其他頁面範例
        若有需要再加即可,預設會跳 404 頁
        """

        try:
            self.object = self.get_object()
        except Http404:
            # 找不到 model
            return redirect('index')

        context = self.get_context_data(object=self.object)

        return self.render_to_response(context)

    def get_context_data(self, **kwargs):
        """另外要傳給樣板的資料"""

        context = super().get_context_data(**kwargs)
        context.update({
            'data': 'my_data',
        })

        return context

    def get_queryset(self):
        """自訂 model 查詢"""

        return MyModel.objects.filter(show=True, id=self.kwargs.get('pk'))

傳統的 View 計算點擊舉例,本篇會以 MyDetailView 為主

views.py

from django.http import HttpRequest
from django.http import HttpResponse
from django.shortcuts import render
from hitcount.models import HitCount
from hitcount.views import HitCountMixin

from models import MyModel


def my_detail(request: HttpRequest) -> HttpResponse:
    """My Deatail View

    Args:
        request (HttpRequest): Http 請求

    Returns:
        HttpResponse: Http 回應
    """

    # 隨便舉例取得一筆資料
    my_model, created = MyModel.objects.get(id=1)

    # first get the related HitCount object for your model object
    hit_count = HitCount.objects.get_for_object(my_model)

    # next, you can attempt to count a hit and get the response
    # you need to pass it the request object as well
    hit_count_response = HitCountMixin.hit_count(request, hit_count)

    # hit_count_response 資料類似如下:
    # UpdateHitCountResponse(hit_counted=True, hit_message='Hit counted: session key')
    # UpdateHitCountResponse(hit_counted=False, hit_message='Not counted: session key has active hit')

    return render(
        request,
        'my_page.html',
        {
            'hits': page_view.hit_count.hits,
        }
    )

url

<int:pk> 這個是給 model 的主鍵
例如假設你的 model 主鍵是 id,它就是 id 值
網址就好像是: http://127.0.0.1:8000/my_path/4
id = 4

urls.py

from django.urls import path
from my_app import views


urlpatterns = [
    path(
        'my_path/<int:pk>',
        views.MyDetailView.as_view(),
        name='my_path'
    ),
]

template

接下來是樣板,假設我使用的樣板是 my_page.html

object 就是網址的 id 傳給 model 得到的資料庫那一筆資料,像是我的 model 有 description

hitcount 是使用插件帶入的,假設我要看點擊次數可以用hitcount.total_hits

my_page.html

<div>{{ object.description }}</div>
<div>觀看次數: {{ hitcount.total_hits }}</div>

最後我要設定什麼時候可以重新計算觀看次數
days 天數
seconds 秒數
其他可以使用 months 設定

settings.py

HITCOUNT_KEEP_HIT_ACTIVE = { 'days': 1, 'seconds': 1, }

Admin

若要在 admin MyModel 顯示觀看次數,可以自行新增欄位

admin.py

from django.contrib import admin

from my_app.models import MyModel


class MyModelAmin(admin.ModelAdmin):
    list_display = ('formatted_hit_count')

    def formatted_hit_count(self, my_model: MyModel):
        return my_model.hit_count.hits

    formatted_hit_count.admin_order_field = 'hit_count'
    formatted_hit_count.short_description = 'Hits'


admin.site.register(MyModel, MyModelAmin)

使用 Template Tags 取得觀看次數

view.py

from .models import MyModel

def example(request):
    return render(
        request,
        'example.html',
        {
            # 取得第一筆資料
            'data': MyModel.objects.first(),
        }
    )

接下來在 example.html 取得觀看次數

example.html

... 略 ...
<!-- 記得要載入 tags -->
{% load hitcount_tags %}

<!-- 總觀看次數 -->
{% get_hit_count for data %}
<!-- 近30天觀看次數 -->
{% get_hit_count for data within "days=30" %}
... 略 ...

官方文件說明: Template Tags

結論

這個插件用 google 開無橫還是可以一直累加
但還是很夠用了,在我寫這篇時,只有英文文件可以看

參考

觀看次數: 1443
pythondjangodjango-hitcount
按讚追蹤 Enjoy 軟體 Facebook 粉絲專頁
每週分享資訊技術

一杯咖啡的力量,勝過千言萬語的感謝。

支持我一杯咖啡,讓我繼續創作優質內容,與您分享更多知識與樂趣!