※このブログではサーバー運用、技術の検証等の費用のため広告をいれています。
記事が見づらいなどの問題がありましたらContactからお知らせください。

<前のページ
【初心者チュートリアル】Django2でブログ作成(Part2)〜アプリケーションを作成〜
次のページ>
【初心者チュートリアル】Django2でブログ作成(Part4)〜DBテーブルの作成~

【初心者チュートリアル】Django2でブログ作成(Part3)〜Modelの作成~

web開発 python3 Django python Djangoチュートリアル

投稿日:2019年11月6日

このエントリーをはてなブックマークに追加
Djangoは簡単にWebアプリケーションを作成できるフレームワークです。この記事は初心者の方向けのDjangoチュートリアルです。

はじめに

この記事について

ここではDjangoにおけるデータベース構造の定義方法について解説していきます。

Djangoはデータベースの管理にORM(Object-Relational-Mapping)を採用していてデータベースの構造をModelを定義することで構成していきます。Modelを使うとSQLより簡単にデータベースの管理を行うことができます。


Modelクラス

DjangoにおけるModelとは

DjangoにおいてModelmodels.pyファイル内に記述されたdjango.db.models.Modelを継承したクラスのことを指します。Modelクラスの変数(attribute)には定義したいデータベースのフィールドを定義します。定義した変数がそのままの名前でデータベースのフィールドになります。
よくあるExeclのような名簿で例えるとシートがModel、カラムのヘッダがフィールド(変数)、それぞれのデータがレコードになります。

Articleモデルを定義

まずはブログの記事としてArticleというModelクラスを定義してみましょう。

sample_blog/blog/models.py
from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User

class Article(models.Model):
    STATUS_CHOICES = (                                          # 公開状態の選択肢
        ('draft', 'Draft'),
        ('published', 'Published'),
    )

    ###### フィールド定義 ##################################################

    title = models.CharField(max_length=250)                     # 記事タイトル
    author = models.ForeignKey(User,                             # 記事筆者
                               on_delete=models.CASCADE,
                               related_name='blog_articles')
    body = models.TextField()                                    # 記事本文
    publish = models.DateTimeField(default=timezone.now)         # 公開日
    created = models.DateTimeField(auto_now_add=True)            # 記事作成日
    updated = models.DateTimeField(auto_now=True)                # 記事最終編集日
    status = models.CharField(max_length=10,                     # 公開状態
                              choices=STATUS_CHOICES,
                              default='draft')
    ########################################################################
    class Meta:
        """
        ModelクラスのMetaクラス。
        記事の並び順やレコードでかぶりがあってはいけないフィールドなど
        ここで指定できる
        公式ドキュメント:
            https://docs.djangoproject.com/ja/2.2/ref/models/options/
        """
        ordering = ('-publish',)                                 # 記事の並び順。新しいものから順に並ぶ。

    def __str__(self):
        """
        モデルを文字列として扱う際何を表示するかを定義するメソッド
        Djangoの管理サイトでの表示や
        print()
        で表示した時などはここが呼ばれる
        """
        return self.title

Articleモデルのフィールドを解説

ここではそれぞれのフィールドについて解説します。

  • title : 記事のタイトルを表します。このように短い文字列になることが予想されるフィールドはmodels.CharField()で定義します。このメソッドは最大文字数を0〜255の値でmax_lengthで指定する必要があります。今回は最大250文字で指定しています。
  • author : 記事の作者を表します。今回はこのフィールドにDjangoでデフォルトで定義されサイトの管理者などを保存するUserモデルを使います。Articleレコードは必ず一つのUserレコードに紐付き、Userレコードは0以上の複数のArticleレコードに紐付かれます。この様な関係を多対一の関係(many-to-one relationshipと言います。この時、authorは対応するUserレコードid(これを外部キーという)を保存します。外部キーを定義するフィールドはmodels.ForeignKey()で定義します。このメソッドは必ず参照先のモデルを第一引数に、さらにレコードが削除された時の動作をon_delete引数で渡すする必要があります。今回のon_delete=models.CASCADEはUserレコードが削除された時、対応するArticleレコードも削除するようにする指示です。また、追加の引数でrelated_name="blog_articles"を渡しています。通常UserモデルにはArticleを参照するための変数が存在しないのですが、related_name引数を指定することでUserモデルからblog_articlesという名前で対応するArticleレコードを参照することができます。
  • body : 記事の本文を表します。記事の本文の文字数は予測できません。このようなフィールドはmodels.TextField()で定義します。このメソッドは必須の引数はなく、models.CharField()と違い最大文字数を指定する必要がありません。
  • publish : 記事の公開日を表します。日時を表す場合models.DateTimeFiled()メソッドを使います。このメソッドには必須の引数はありません。今回はオプションのdefault引数を指定しています。この引数は値を渡さなかった場合入る値を表します。default=datetime.nowでその時の時間を自動的に入ります。datetime.now()ではないことに注意してください。
  • created : 記事の作成日を表します。ここでは引数にauto_now_add=Trueを渡しています。この場合、createdに値を渡さなかった場合、Articleレコードを初めて作成したときの日時が自動的に入ります。デフォルトではauto_now_addFalseになっています。
  • updated : 記事の最終編集日を表します。ここでは引数にauto_now=Trueを渡しています。この場合、updatedに値を渡さなかった場合、Articleレコードを最後に編集した時刻が入ります。
  • status : 記事の公開状態を表します。statusdraft(下書き状態)とpublished(公開状態)の2つの値だけになることにし、デフォルトでは記事は必ずdraft(下書き状態)になるようにしましょう。そうしたい場合には、引数には必須のmax_lengthに加えて、choices=STATUS_CHOICESdefault="draft"を渡して上げます。入る文字列が決まっている場合、choices引数で選択肢を指定することでこの2つの文字列以外が入ることを防ぐことができるのです。

フィールドをどのメソッドで指定すれば良いのかはそのフィールドに入る値によって変わります。悩んだ時にはDjangoの公式ドキュメントを参照しましょう。

(Django2.2公式ドキュメント:https://docs.djangoproject.com/ja/2.2/ref/models/fields/

Metaクラスについて

Metaクラスではそのモデルの設定の様なものを書くことができます。例えば、今回の様な記事のモデルの場合、デフォルトで全ての記事を取得したときに公開日(publish)のフィールドの値が新しいものから順に並んでいると使いやすそうです。そのような場合ordering変数にタプルを渡します。

class Article(models.Model):
    [...]
    class Meta:
        ordering = ('-publish',)                                 # 記事の並び順。新しいものから順に並ぶ。

ここでordering=("publish")ではなくordering=("-publish")になっていることに注意してください。ordering引数は渡された値が小さい順に並べます。つまりordering=("publish",)にするとpublishが小さい順、つまりpublishの日時が古い順に並んでしまうのです。その順序を逆にしたいときには今回の様に引数のフィールド名の先頭に - をつけます。

class Article(models.Model):
    [...]
    class Meta:
        ordering = ('publish',)                                 # これだと古い順に並びます。

Metaクラスには他にも指定できる値が色々あります。なれてきたら色々探してみましょう。

(Django2.2公式ドキュメント:https://docs.djangoproject.com/ja/2.2/ref/models/options/

__str__メソッドについて

__str__メソッドはPython3でクラスを文字列として表示する際に呼ばれるクラスです。Djangoの管理サイトで表示される名前もここで返される値になります。


さいごに

まとめ

  • Djangoではデータベース管理にORMを使う。
  • テーブルを定義する場合にはModelクラスを定義する。
  • Modelクラスでは定義したいカラムを変数として定義する。
  • ModelクラスではMetaクラスで特定の変数(orderingunique_togetherなど)を定義することで振る舞いをカスタマイズできる。
このエントリーをはてなブックマークに追加

<前のページ
【初心者チュートリアル】Django2でブログ作成(Part2)〜アプリケーションを作成〜
次のページ>
【初心者チュートリアル】Django2でブログ作成(Part4)〜DBテーブルの作成~

関連記事

記事へのコメント