Djangoメモ(29) : migrateでモデルに閲覧数カウント用のフィールドを追加
A Complete Beginner's Guide to Djangoのチュートリアルを参考にモデルに閲覧数カウント用のフィールドを追加してみる。
モデルにフィールド追加
migrate
コマンドを使ってTopicモデルに閲覧数カウント用のviewsフィールドを追加してみる。
作業を進める前に適用していないマイグレーションがないか確認しておく。No migrations to apply
となればよい。
$ python manage.py migrate Operations to perform: Apply all migrations: admin, auth, boards, contenttypes, sessions Running migrations: No migrations to apply.
まずboards/models.py
にフィールドの情報を追加する。
class Topic(models.Model): subject = models.CharField(max_length=255) last_updated = models.DateTimeField(auto_now_add=True) board = models.ForeignKey(Board, on_delete=models.CASCADE, related_name='topics') starter = models.ForeignKey(User, on_delete=models.CASCADE, related_name='topics') views = models.PositiveIntegerField(default=0) # <- here def __str__(self): return self.subject
閲覧数は正の整数なのでviews
をPositiveIntegerField
として追加している。
migrateコマンド実行
モデルにフィールドを追加したのでマイグレーションを実行してデータベースに反映してみる。
最初にmakemigrations
コマンドでマイグレーションファイルを作成する。
$ python manage.py makemigrations Migrations for 'boards': boards/migrations/0002_topic_views.py - Add field views to topic
コマンドを実行するとboards/migrations/0002_topic_views.py
というマイグレーションファイルが作成される。
ファイルの中身は以下のようにフィールドを追加する処理が記述されている。
# Generated by Django 2.0.2 on 2018-03-26 14:14 from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ ('boards', '0001_initial'), ] operations = [ migrations.AddField( model_name='topic', name='views', field=models.PositiveIntegerField(default=0), ), ]
マイグレーションを実行する前に現在の状態をshowmigrations
で確認してみる。
以下のように0002_topic_views
は[X]
となっておらず適用されていないことがわかる。
$ python manage.py showmigrations boards boards [X] 0001_initial [ ] 0002_topic_views
migrate
コマンドでマイグレーションを実行する。
$ python manage.py migrate Operations to perform: Apply all migrations: admin, auth, boards, contenttypes, sessions Running migrations: Applying boards.0002_topic_views... OK
実行後はマイグレーションが適用済みになり、データベースのboards_topic
テーブルにviews
カラムが追加されている。
$ python manage.py showmigrations boards boards [X] 0001_initial [X] 0002_topic_views
ビュー、テンプレートの変更
フィールドは追加できたので閲覧数をカウントできるようにboards/views.py
を編集する。
from django.shortcuts import get_object_or_404, render from .models import Topic def topic_posts(request, pk, topic_pk): topic = get_object_or_404(Topic, board__pk=pk, pk=topic_pk) topic.views += 1 topic.save() return render(request, 'topic_posts.html', {'topic': topic})
topic.views += 1
とtopic.save()
でビュー関数が呼ばれる度にカウントアップして保存しているので閲覧数がカウントできる。
次に閲覧数を表示するようにtemplates/topics.html
を編集。
{% for topic in topics %} <tr> <td><a href="{% url 'topic_posts' board.pk topic.pk %}">{{ topic.subject }}</a></td> <td>{{ topic.starter.username }}</td> <td>{{ topic.replies }}</td> <td>{{ topic.views }}</td> <!-- here --> <td>{{ topic.last_updated }}</td> </tr> {% endfor %}
試しに何回かアクセスしてみるとViewsの数が増えていくことが確認できる(ただし、これだと同じユーザーで何回もカウントしてしまうので後のチュートリアルで変更するとのこと)。
まとめ
- データベーススキーマを変更するにはまず
models.py
を編集 makemigrations
でマイグレーションファイルを作成migrate
でマイグレーションを実行showmigrations
でマイグレーションの状態を確認- ビュー関数で
topic.views += 1
のようにして閲覧数をカウント