Python Django 入門トップページ


このページは Django version 3 系の情報です.新たな version 4 系の情報はこちらからどうぞ.

Django によるコメント掲示板の開発:目次

  1. プロジェクトの作成
  2. Git でコミット
  3. Web サーバを起動しておく
  4. Config
  5. Comments アプリケーションを作る
  6. はじめてのビューを作成する
  7. モデルを作る
  8. アプリケーションを有効にする
  9. マイグレーション
  10. テストデータの設定
  11. データベースからコメント一覧を取得して表示してみよう
  12. Bootstrap の導入
  13. コメントの詳細表示
  14. urls.pyの書き方
  15. HTML のテンプレート化
  16. コメントの新規投稿
  17. コメントの編集機能を追加する
  18. さらにテンプレート化
  19. モデル,マイグレーションファイル,フォームの関連
  20. 入力内容の検証(バリデーション)
  21. コメントを削除する
  22. 一覧を逆順にする
  23. ページネーション
  24. フラッシュメッセージ
  25. Static コンテンツの設置
  26. 更新や削除にもフラッシュメッセージを表示
  27. テストの自動化を実現しよう
  28. デバッグツールバーを使う
  29. generic モジュールを使わずにコメント一覧を取得する
  30. コメント一覧のページネーション
  31. 一覧の表示順序を制御する
  32. generic モジュールを使わずにコメントの詳細を表示する
  33. コメント詳細にページ送り機能を作成する
  34. generic モジュールを使わずにコメント登録機能を作成する
  35. generic モジュールを使わずにコメント編集機能を作成する
  36. generic モジュールを使わずにコメント削除機能を作成する

Django によるコメント掲示板の開発

モデル,マイグレーションファイル,フォームの関連

このタイミングでモデルとマイグレーションファイル,フォームの要素についてそれらの関連を確認しておこう.Django は,記述したモデルからマイグレーションファイルやフォームを自動的に作成できることが特長である.まず,すでに記述したモデルの内容を確認する.

comments/models.py (抜粋)
class Comment(models.Model):
    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)

ここで実行したマイグレーションのコマンドによって生成されたマイグレーションファイルには 0001 から順に番号が振られる.その内容を確認すると,モデルに記述したフィールドが設定されていることがわかる.

comments/migrations/0001_initial.py
# Generated by Django 3.1.1 on 2020-09-06 16:44

from django.db import migrations, models


class Migration(migrations.Migration):

    initial = True

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='Comment',
            fields=[
                ('id', models.AutoField(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)),
            ],
        ),
    ]

sqlite3 でテーブルのスキーマを確認すると,全てのカラムに NOT NULL 属性が設定されていることがわかる.

(base) C:\Users\lecture\Documents\django\django_comment>sqlite3 db.sqlite3 ⏎
SQLite version 3.31.1 2020-01-27 19:55:54
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
);
sqlite> .exit ⏎

(base) C:\Users\lecture\Documents\django\django_comment>

また,投稿フォームや更新フォームでは title と body だけが表示されるようにした.

comments/forms.py (抜粋)
class CommentForm(forms.ModelForm):

    class Meta:
        model = Comment
        fields = ('title', 'body')
        widgets = {
              'title': forms.TextInput(attrs={
              'class': 'form-control'
            }),
              'body': forms.TextInput(attrs={
              'class': 'form-control'
            }),
        }
        labels = {
            'title': 'タイトル',
            'body': '本文',
        }

Web ブラウザで新規投稿フォームを表示して,そのソースコードを確認する(Google Chrome では「表示」→「開発 / 管理」→「ソースを表示」メニューを,Firefox では「ツール」→「ウェブ開発」→「ページのソース」メニューをクリックする).

生成された新規投稿フォームの HTML ソース
<div class="container">
  <h1 class="my-5">コメントの投稿</h1>
  <form method="POST">
    <input type="hidden" name="csrfmiddlewaretoken" value="K8udatbth8GlhLZmCmPQfiXoZKnOmkHq2yhCV7J2S4dleowCpQ58oicrKPOae2KW">
    <p><label for="id_title">タイトル:</label> <input type="text" name="title" class="form-control" maxlength="200" required id="id_title"></p>
<p><label for="id_body">本文:</label> <input type="text" name="body" class="form-control" maxlength="1000" required id="id_body"></p>
    <button type="submit" class="btn btn-primary">コメントを投稿する</button>
  </form>
</div>

上のソースを見ると,title と body のテキストボックスには required 属性が設定されている.これは,データベースのカラムに NOT NULL 属性が設定されているからである.よって,新規投稿フォームや更新フォームで title や body を空のままにして投稿しようとしても,Web ブラウザがその検証を行ってくれる.

django-comment-17

Can I Use (https://caniuse.com/) で確認すると,required 属性はほとんどの Web ブラウザでサポートされているが,HTML の全ての機能が全ての Web ブラウザでサポートされているとは限らない.また,半角スペースだけが入力されたときには Web ブラウザを通過して,Django 側でエラーになるという問題点がある.更に,空の投稿は検証できるが,title や body にそれぞれの上限文字数である 200 文字や 1000 文字以上が投稿されたときにのエラー表示なども Web ブラウザだけに任せるのではなく,Django 側でも検証しておいたほうが安全である.次に,入力内容の検証を行ってみよう.

目次に戻る