【Django】Positive Integer Fieldから閲覧数(PV)を取得して一覧表示させる
今回は閲覧数を獲得するために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)を獲得した順番に表示させていきたいと思います。
閲覧数の要素を取得したいので、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機能を試して行ければと思います。
最後までご覧いただきありがとうございます。