Python Django 入門トップページ


ユーザ認証とコメント掲示板の開発

  1. プロジェクトの概要
  2. プロジェクトの作成と初期設定
  3. アプリケーションの作成と有効化
  4. ルートの記述
  5. ビューの定義
  6. HTML のテンプレート化
  7. HTML ファイルの作成
  8. Web ページ雛形の表示確認
  9. トップページの作成
  10. データベースのマイグレーション
  11. ユーザの作成
  12. ユーザ認証機能の実装
  13. セッション情報の確認
  14. ユーザ認証の状態を表示
  15. Navbar を設置
  16. モデルの作成とマイグレーション
  17. テストデータの投入
  18. コメントの一覧表示
  19. ページネーションと更新逆順表示
  20. コメント投稿機能の実装
  21. フラッシュメッセージ
  22. コメント詳細表示ページの実装
  23. 投稿者のユーザ名とメールアドレスの表示
  24. 投稿者であるかどうかの判断
  25. 編集・更新機能の実装
  26. コメント削除機能の実装
  27. Navbar の調整
  28. Profile の表示
  29. Profile の編集と更新
  30. パスワードの変更
  31. 管理サイトの準備
  32. 管理ユーザの登録
  33. 管理サイトへのログインとスタッフの登録
  34. グループの追加と権限の付与
  35. 管理サイトに comments アプリケーションを登録
  36. Comments アプリケーションから管理サイトへ

ユーザ認証とコメント掲示板の開発

モデルの作成とマイグレーション

目次に戻る

モデルを作る

これまでのステップでユーザ認証の機能と各ページのデザインの雛形ができました.ここからコメント掲示板の主要機能を実装していきます.以降の内容はここで開発したシステムと概ね同じですが,コメントに投稿者の情報を付与する点が異なります.

まずは Comment モデルを作成します.コメントには「title」「body」「投稿日時」「最終更新日時」の他に,投稿者を意味する「owner」を準備する.「Userモデル」と「Commentモデル」は「一対多」のリレーションシップになることに注意してください.リレーションシップの詳細はここで確認してください.

comments/models.py
from django.db import models
from django.contrib.auth.models import User

# Create your models here.
class Comment(models.Model):
    title = models.CharField(max_length=200)
    body = models.CharField(max_length=1000)
    owner = models.ForeignKey(User, on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

目次に戻る

マイグレーションファイルを生成

今作成した models.py からデータベースにテーブルを登録するためのマイグレーションファイルを生成します.

(py39) C:\Users\lecture\Documents\django\django_comment_auth>python manage.py makemigrations comments ⏎
Migrations for 'comments':
  comments\migrations\0001_initial.py
    - Create model Comment

(py39) C:\Users\lecture\Documents\django\django_comment_auth>

この操作で生成されたファイルの中身を確認しておきましょう.

comments/migrations/0001_initial.py
# Generated by Django 4.0.6 on 2022-07-27 18:49

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

    initial = True

    dependencies = [
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
    ]

    operations = [
        migrations.CreateModel(
            name='Comment',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('title', models.CharField(max_length=200)),
                ('body', models.CharField(max_length=1000)),
                ('created_at', models.DateTimeField(auto_now_add=True)),
                ('updated_at', models.DateTimeField(auto_now=True)),
                ('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
            ],
        ),
    ]

どのマイグレーションが実行されているかを確認します.ここの手順ですでにマイグレーションを実行しているので,comments アプリケーション以外は実行されてテーブルが生成されていることがわかります.

(py39) C:\Users\lecture\Documents\django\django_comment_auth>python manage.py showmigrations ⏎
admin
 [X] 0001_initial
 [X] 0002_logentry_remove_auto_add
 [X] 0003_logentry_add_action_flag_choices
auth
 [X] 0001_initial
 [X] 0002_alter_permission_name_max_length
 [X] 0003_alter_user_email_max_length
 [X] 0004_alter_user_username_opts
 [X] 0005_alter_user_last_login_null
 [X] 0006_require_contenttypes_0002
 [X] 0007_alter_validators_add_error_messages
 [X] 0008_alter_user_username_max_length
 [X] 0009_alter_user_last_name_max_length
 [X] 0010_alter_group_name_max_length
 [X] 0011_update_proxy_permissions
 [X] 0012_alter_user_first_name_max_length
comments
 [ ] 0001_initial
contenttypes
 [X] 0001_initial
 [X] 0002_remove_content_type_name
sessions
 [X] 0001_initial

(py39) C:\Users\lecture\Documents\django\django_comment_auth>

マイグレーションを実行します.これにより comments アプリケーションのテーブルが生成されます.

(py39) C:\Users\lecture\Documents\django\django_comment_auth>python manage.py migrate ⏎
Operations to perform:
  Apply all migrations: admin, auth, comments, contenttypes, sessions
Running migrations:
  Applying comments.0001_initial... OK

(py39) C:\Users\lecture\Documents\django\django_comment_auth>

マイグレーションの実行状況を確認します.

(py39) C:\Users\lecture\Documents\django\django_comment_auth>python manage.py showmigrations ⏎
admin
 [X] 0001_initial
 [X] 0002_logentry_remove_auto_add
 [X] 0003_logentry_add_action_flag_choices
auth
 [X] 0001_initial
 [X] 0002_alter_permission_name_max_length
 [X] 0003_alter_user_email_max_length
 [X] 0004_alter_user_username_opts
 [X] 0005_alter_user_last_login_null
 [X] 0006_require_contenttypes_0002
 [X] 0007_alter_validators_add_error_messages
 [X] 0008_alter_user_username_max_length
 [X] 0009_alter_user_last_name_max_length
 [X] 0010_alter_group_name_max_length
 [X] 0011_update_proxy_permissions
 [X] 0012_alter_user_first_name_max_length
comments
 [X] 0001_initial
contenttypes
 [X] 0001_initial
 [X] 0002_remove_content_type_name
sessions
 [X] 0001_initial

(py39) C:\Users\lecture\Documents\django\django_comment_auth>

SQLite を使ってテーブルが生成されていることも確認しておきます.ここで,生成されたテーブル名が アプリケーション名_モデル名 になっていることを確認してください.さらに,models.py では外部キーを owner と指定しましが,テーブルの列名は owner_id になっていることにも注意してください.

(py39) C:\Users\lecture\Documents\django\django_comment_auth>sqlite3 db.sqlite3 ⏎
SQLite version 3.38.2 2022-03-26 13:51:10
Enter ".help" for usage hints.
sqlite> .tables ⏎
auth_group                  comments_comment
auth_group_permissions      django_admin_log
auth_permission             django_content_type
auth_user                   django_migrations
auth_user_groups            django_session
auth_user_user_permissions
sqlite> .schema comments_comment ⏎
CREATE TABLE IF NOT EXISTS "comments_comment" (
    "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
    "title" varchar(200) NOT NULL,
    "body" varchar(1000) NOT NULL,
    "created_at" datetime NOT NULL,
    "updated_at" datetime NOT NULL,
    "owner_id" integer NOT NULL
        REFERENCES "auth_user" ("id")
        DEFERRABLE INITIALLY DEFERRED
);
CREATE INDEX "comments_comment_owner_id_26de7a7f" ON "comments_comment" ("owner_id");
sqlite> .exit ⏎

(py39) C:\Users\lecture\Documents\django\django_comment_auth>

次のページではいま生成したテーブルにテストデータを投入してみよう.

なお,マイグレーションの詳細(テーブル生成後の列の追加など)はこちらを参照してください.

目次に戻る