Django django-hitcount 取得熱門文章 累積觀看次數


建立時間: 2022年8月5日 14:32
更新時間: 2023年9月14日 08:50

說明

之前介紹過 django-hitcount 實作觀看次數
這次分享如何取得熱門文章和累積觀看次數

前置作業

若您還沒使用過 django-hitcount 或者還沒有在 model 建立 hitcount 欄位
請參考 Django django-hitcount 實作觀看次數

Article Model

以下使用 Article Model 示範

models.py

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

class Article(models.Model, HitCountMixin):
    """文章
    """

    # 標題
    title = models.CharField(max_length=200, help_text='輸入標題')
    # 內文
    content = content = models.TextField(blank=True)
    # hit-count 外掛,用來記錄觀看次數
    hit_count_generic = GenericRelation(
        HitCount, object_id_field='object_pk',
        related_query_name='hit_count_generic_relation'
    )

    def __str__(self) -> str:
        return self.title

熱門文章

get_popular_articles 函式複製在 views.py 之後就可以在要 render 的地方使用此函式

views.py

from datetime import timedelta
from django.db.models import Count
from django.db.models.query import QuerySet
from django.utils import timezone

# 自己的 app model
from your_app.models import Article


def get_popular_articles(days: int, count: int = 10) -> QuerySet:
    """取得熱門文章

    Args:
        days (int): 查詢天數,0為總天數
        count (int, optional): 筆數. Defaults to 10.

    Returns:
        QuerySet: 熱門文章
    """

    if count <= 0:
        # 防呆機制
        count = 10

    if days <= 0:
        # 總天數和防呆機制
        return Article.objects.all().order_by(
            '-hit_count_generic__hits'
        )[:count]

    period = timezone.now() - timedelta(days=days)

    return Article.objects.filter(
        hit_count_generic__hit__created__gte=period
    ).annotate(
        counts=Count('hit_count_generic__hit')
    ).order_by(
        '-counts'
    )[:count]

累積觀看次數

get_total_hits 函式複製在 views.py 之後就可以在要 render 的地方使用此函式

views.py

from datetime import timedelta
from django.db.models import Count
from django.db.models.query import QuerySet
from django.utils import timezone

# 自己的 app model
from your_app.models import Article


def get_total_hits(days: int) -> int:
    """取得總共點擊次數

    Args:
        days (int): 天數,0代表所有的時間

    Returns:
        int: 總共點擊次數
    """

    if days <= 0:
        result = Article.objects.aggregate(count=Count('hit_count_generic__hit'))
    else:
        period = timezone.now() - timedelta(days=days)
        result = Article.objects.filter(
            hit_count_generic__hit__created__gte=period
        ).aggregate(
            count=Count('hit_count_generic__hit')
        )

    return result['count']

使用範例

假設要在 index 顯示熱門文章和累積觀看次數

views.py

from django.http import HttpRequest
from django.http import HttpResponse
from django.shortcuts import render


def index(request: HttpRequest) -> HttpResponse:
    # 熱門文章
    popular_articles = get_popular_articles(0)
    # 總累積觀看次數
    total_hits = get_total_hits(0)

    return render(
        request,
        'index.html',
        {
            'popular_articles': popular_articles,
            'total_hits': total_hits,
        }
    )
觀看次數: 1023
countdjangohitpopularpopularity熱門文章觀看次數
按讚追蹤 Enjoy 軟體 Facebook 粉絲專頁
每週分享資訊技術

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

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