【Django】Positive Integer Fieldから閲覧数(PV)を取得して一覧表示させる

投稿日 2019年7月3日 >> 更新日 2023年3月2日

今回は閲覧数を獲得するためにDjangoのPositiveIntegerFieldを使って簡単なブログサイトを例に表示させていきたいと思います。

GoogleアナリティクスAPIを使ったトレンドの表示についてはこちらです。

ブログサイトなどで見かける「よく見られています」や「人気記事」のような表示もさせて、より動的なサイトにしていきます。

とは言ってもフロントエンドではHTMLのみ使うので、レイアウトなどは各々で楽しんで進めてください。

実行環境&使用ライブラリ

実行環境
Windows Subsystem for Linux
Python 3.6.8
pip 9.0.1
使用ライブラリ ライセンス
Django==2.2.6 BSD

簡単なブログを作成

※イメージ

閲覧数・TOP PV表示以前のソースコードは以下からコピペしてください。

# project/project/settings.py

INSTALLED_APPS = [
    'blog.apps.BlogConfig',

LANGUAGE_CODE = 'ja'
TIME_ZONE = 'Asia/Tokyo'
# project/models.py

from django.db import models


class Blog(models.Model):
    title = models.CharField(max_length=50)
    text = models.TextField()
    created_at = models.DateField(auto_now_add=True)

    def __str__(self):
        return self.title
# project/blog/admin.py

from django.contrib import admin
from .models import Blog


admin.site.register(Blog)

モデルを作成したのでshellにてデータベースにモデルを反映させます。そのあとにスーパーユーザーも設定しておきます。


$ python3 manage.py makemigrations

$ python3 manage.py migrate

$ python3 manage.py createsuperuser
# project/project/urls.py

from django.contrib import admin
from django.urls import path, include


urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('blog.urls')),
]
# project/blog/urls.py

from django.urls import path
from . import views


app_name = 'blog'

urlpatterns = [
        path('', views.index, name='index'),
        path('detail/<int:blog_id>/', views.detail, name='detail'),
]
# project/blog/views.py

from django.shortcuts import render, get_object_or_404
from .models import Blog


def index(request):
    blog = Blog.objects.order_by('-id')
    return render(request, 'blog/index.html',
                    {'blog': blog })


def detail(request, blog_id):
    blog = get_object_or_404(Blog, id=blog_id)
    return render(request, 'blog/detail.html', {'blog': blog })

templatesフォルダを作成しhtmlファイルを作成します。

<!-- project/blog/templates/blog/base.html -->

<!doctype html>
<html>
    <head>

        <title>TODO</title>

    </head>
    <body>
        <h1>Blog閲覧数獲得</h1>

    {% block content %}
        {% endblock %}

    </body>
</html>
<!-- project/blog/templates/blog/index.html -->

{% extends 'blog/base.html' %}

{% block content %}

    <h1>一覧</h1>

    {% for blog in blog %}
        <ul>
            <li>
                {{ blog.created_at }}
                {{ blog.title }}
                <a href="{% url 'blog:detail' blog_id=blog.id %}">詳細</a>
            </li>
        </ul>
    {% endfor %}

{% endblock %}
<!-- project/blog/templates/blog/detail.html -->

{% extends 'blog/base.html' %}

{% block content %}

    <p>{{ blog.updated_at }}</p>
    {{ blog.text }}<hr />
    <br>
    <a href="{% url 'blog:index' %}">トップページに戻る</a>

{% endblock %}

ここまでできたらadmin管理画面にて3記事程作成しておきましょう。

表示例

閲覧数取得用のフィールドを作成

まずはモデルフィールであるPositiveIntegerFieldをmodels.pyにて設定します。

# project/blog/models.py

from django.db import models


class Blog(models.Model):
    title = models.CharField(max_length=50)
    text = models.TextField()
    created_at = models.DateField(auto_now_add=True)
    views = models.PositiveIntegerField(default=0)  # ←ここ

    def __str__(self):
        return self.title

コードを差し込んだらデータベースにモデルを反映させます。


$ python3 manage.py makemigrations

$ python3 manage.py migrate

次にviews.pyにて記事詳細のidと紐づけます。

# project/blog/views.py

from django.shortcuts import render, get_object_or_404
from .models import Blog


def index(request):
    .............
    .............


def detail(request, blog_id):
    blog = get_object_or_404(Blog, id=blog_id)
    blog.views += 1    # ←ここ
    blog.save()            # ←ここ
    return render(request, 'blog/detail.html', {'blog': blog })

テンプレートにviewsフィールドを渡します。

<!-- project/blog/templates/blog/index.html -->

{% extends 'blog/base.html' %}

{% block content %}

    <h1>一覧</h1>

    {% for blog in blog %}
        <ul>
            <li>
                {{ blog.created_at }}
                {{ blog.title }}
                <a href="{% url 'blog:detail' blog_id=blog.id %}">詳細</a>
                <!-- ここ -->
                (閲覧数 {{ blog.views }}
            </li>
        </ul>
    {% endfor %}

{% endblock %}

まずは閲覧数を表示させることができました。

この後は、多く閲覧数(PV)を獲得した順番に表示させていきたいと思います。

TOP PVの表示

閲覧数の要素を取得したいので、order_byにてviewsフィールドを指定します。views.pyのindex関数でTOP PV用の変数を作りrender関数に渡します。

# project/blog/views.py

def index(request):
    blog = Blog.objects.order_by('-id')
    blog_views = Blog.objects.order_by('-views')  # ←ここ
    return render(request, 'blog/index.html',
                    {'blog': blog, 'blog_views': blog_views })  # ←ここ

なお、order_by('-views')[:3]とすることで三つまでの要素を表示させることもできます。

それではTOP PV用のコードをindex.htmlで記述しましょう。

<!-- project/blog/templates/blog/index.html -->

{% extends 'blog/base.html' %}

{% block content %}

    <h1>一覧</h1>

    {% for blog in blog %}
        ............
        ............
    {% endfor %}

    <h1>TOP PV</h1>

    {% for blog in blog_views %}
        <ul>
            <li>
                <a href="{% url 'blog:detail' blog_id=blog.id %}">{{ blog.title }}</a>
            </li>
        </ul>
    {% endfor %}

{% endblock %}

表示例

詳細やTOP PVをポチポチ押してみると、しっかり機能できていると思います。

こういった機能を簡単に実現できてしまうのでDjangoは手放せませんね。

まだまだ他のDjango機能を試して行ければと思います。

最後までご覧いただきありがとうございます。

一覧へ戻る