Djangoモデル層とは何か?データベースとの関係を説明します。

こんにちは!TodoONadaの土門(@daikidomon)です。

皆さん、こんにちは。

今日はDjangoのモデルについて紹介したいと思います。

これまでの記事: これまでの記事ではファイルの構造は以下の様になっております。

mysite
├── db.sqlite3
├── hello
│   ├── admin.py
│   ├── apps.py
│   ├── __init__.py
│   ├── migrations
│   │   ├── __init__.py
│   │   └── __pycache__
│   │   └── __init__.cpython-36.pyc
│   ├── models.py
│   ├── __pycache__
│   │   ├── admin.cpython-36.pyc
│   │   ├── __init__.cpython-36.pyc
│   │   ├── models.cpython-36.pyc
│   │   ├── urls.cpython-36.pyc
│   │   └── views.cpython-36.pyc
│   ├── static
│   │   └── css
│   │   ├── bootstrap.min.css
│   │   └── style.css
│   ├── templates
│   │   └── index.html
│   ├── tests.py
│   ├── urls.py
│   └── views.py
├── manage.py
└── mysite
├── asgi.py
├── __init__.py
├── __pycache__
│   ├── __init__.cpython-36.pyc
│   ├── settings.cpython-36.pyc
│   ├── urls.cpython-36.pyc
│   └── wsgi.cpython-36.pyc
├── settings.py
├── urls.py
└── wsgi.py

この記事まででデータベースの設計とアプリのインストールを終わらせてます。

初めての方は初期設定から確認をお願いします。

あわせて読みたい
[Django] インストール後にやるべきsettings.pyの設定。settings.pyを徹底解説 今回の記事では、Djangoでプロジェクト作成後にやっておきたい初期設定について紹介したいと思います。 各バージョンは以下になります。 python3django3 ※今回の手順で...
目次

Djangoのモデルとは何か?

データベースのテーブルを設計した後、アプリ開発でデータベースにテーブルを作る必要があります。

Djangoはアプリのテーブルを作成する時にはモデル内にテーブルの定義を書きます。

これはモデル(自動生成されたmodels.py)の中に定義を書き、コマンドを入力すればデータベースにテーブルを生成することができます。

例のmodels.pyはいかになります。(Djangoオフィシャルページより)

from django.db import models

class Person(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)

これはデータベースないで以下の様にテーブルを作るのと同じです。

CREATE TABLE myapp_person (
    id serial NOT NULL PRIMARY KEY,
    first_name varchar(30) NOT NULL,
    last_name varchar(30) NOT NULL
);

Djangoではmodels.フィールドのタイプで作られております。

公式ページの参考は以下になります。

参考:Djangoのmodels

モデルのフィールドタイプの説明

モデルのフィールドタイプは以下になります。

フィールドの型説明補足
AutoField自動的にインクリメントする IntegerField です。
通常は直接指定する必要はありません。
指定しない場合は、自動的にモデルに追加されます。
自動インクリメントのプライマリーキーフィールド :https://docs.djangoproject.com/ja//3.0/topics/db/models/#automatic-primary-key-fields
BigAutoField64 ビットの数値。
1 から 9223372036854775807 までの数を扱えます。
それ以外はAutoField と同じです。
BigIntegerField64 ビットの数値。
-9223372036854775808から9223372036854775807まで適応されます。
それ以外はIntegerfieldと同じです。
BinaryField未加工のバイナリデータ。 Bytes、bytearray、 memoryviewに割り当てることができる。デフォルトでeditableはFalseに設定されてるのでModelFormでは使えない。BinaryField.max_lengthという引数がある。最大長さを示している。
BooleanFieldTrue/Falseを示す値。デフォルトの値はNone。
adminではチェックボックスになっている。
CharField文字列のフィールドです。
テキストを入れたい場合TextFieldをお使いください。
max_lengthの指定が必須です。
DateField日付けのフィールドです。
オプションがいくつかあります。
DateField.auto_now_add:オブジェクトが保存される度に自動的に現在の日付をセットします。現在の日付が常に使われます。オーバーライドできるデフォルト値ではありません。
auto_now_add:オブジェクトが最初に作成されるとき、自動的にフィールドに現在の日付をセットします。現在の日付が常に使われます。オーバーライドできるデフォルト値ではありません。
DateTimeField日付と時刻のフィールドです。
DateFieldと同じオプションがあります。
DecimalFiel固定精度の少数です。PythonのDecimal型として扱います。
必須の引数が二つあります。
DecimalField.max_digits:数値内で使える最大桁数。
DecimalField.decimal_places:数値と保持される小数点以下の位の数。
DurationField時刻の期間を表します。Pythonのtimedeltaにモデル化されてます。
データの型はPostgreSQL はinterval、oracleではINTERVAL DAY(9) TO SECOND(6)。
PostgreSQL以外のデータベースでDurationFieldとDateTimeFieldの比較は期待通りに機能しない。
EmailFieldメールアドレスです。同時にメールアドレスの値をチェックします。
FileFieldファイルアップロードのフィールド。Upload_toでアップロードアップロードディレクトリとファイル名を二つの方法でセットする事ができます。もしデフォルトのFileSystemStorageを使っている場合MEDIA_ROOTのディレクトリの下に行き、その下で保存する場所を使います。FileFieldの具体的な説明は以下にあります。
https://docs.djangoproject.com/ja/3.0/ref/models/fields/#filefield
FilePathField特定のディレクトリの下のファイル名を保存するフィールドです。
必須の引数はpathです。FilePathField が取得するディレクトリへのファイルシステムのパスです。
FilePathFieldの具体的な説明は以下になります。
https://docs.djangoproject.com/ja/3.0/ref/models/fields/#filepathfield
FloatFieldpythonの浮動小数点数です。DecimalFieldと似ていますが、DecimalFieldはDecimal型、FloatFieldはFloat型です。
ImageFieldFileFieldから全ての属性とメソッドを継承して、さらにアップロードされたオブジェクトが有効な画像であることを検証します。FileFieldに加えてImageField.height_field、ImageField.width_fieldがあります。Pillowライブラリーが必要です。
IntegerField整数フィールドです。
GenericIPAddressFieldIPv4 か IPv6 のアドレスの文字列フォーマットです。
NullBooleanFieldBooleanFieldと同じでnull=TrueのBooleanFieldの代わりに使えます。
PositiveIntegerField正整数です(0含む)。0 から 2147483647 までの値が使えます。
PositiveSmallIntegerField正整数です(0含む)。0 から 32767 までの値が使えます。
SlugField文字列でラベルの様なフィールドです。URLで使うことがあります。SlugField.allow_unicode:Trueに設定すればASCIIとUNICODEの文字列を受け入れます。デフォルトはFalseです。
SmallAutoFieldAutoFieldと同じで1から32767が使えます。Django3.0以後追加。
SmallIntegerFieldIntegerFiledと同じで-32768 から 32767 までの値が使えます。
TextFieldテキストフィールドです。(文字が多すぎてテキストになる場合に使います。)
TimeField時刻のフィールドです。DateField と同じ自動入力されるオプションを受け入れます。
URLFieldURLのフィールドです。同時にURLの検証もします。
UUIDFieldUUID (Universally Unique Identifier)のフィールドです。Uuidをインポートする必要があります。

参考: フィールドタイプ

モデルのリレーションフィールド

モデルのリレーションフィールドは以下になります。

リレーションシップフィールド説明補足
ForeignKeyデータベースのForeign Keyと同じで多対一のリレーションです。必須なオプションが二つあります。参照先とon_deleteでございます。on_deleteは参照する先が削除された場合、設定次第で残すか一緒に削除するかを決める因数です。https://docs.djangoproject.com/ja/3.0/ref/models/fields/#foreignkey
ManyToManyField多対多のリレーションです。必須なオプションはForeignKeyと同じく二つあります。(内容も同じです)これを使うとデータベースに中間のテーブルをつくります。テーブル名は自動生成自動生成でございます。https://docs.djangoproject.com/ja/3.0/ref/models/fields/#manytomanyfield
OneToOneField一対一のリレーションです。ForeignKeyと似ていますが、リレーションが逆の場合一つしかオブジェクトが返ってきません。必須なオプションは参照先でございます。https://docs.djangoproject.com/ja/3.0/ref/models/fields/#onetoonefield

参考:リレーションフィールド

モデルのフィールドオプションの説明

モデルのフィールドオプションの説明は以下になります。

フィールドオプション説明補足
nullTrueの場合、Nullとして空の値をデータベースに入れます。
デフォルトはFalseでございます。
null = Trueと使えるのは文字列型ではないフィールドの型です。
blankTrueの場合、フィールドに空白を入れる事を許されます。blankはバリデーションと関連します。フォームを入れる時blank=Trueの場合空の値でも通ります。Blank=Falseの場合空の値は通りません。
choiceタプルのリストを選択しとします。[('A','B'),('C','D'),…]。この場合エントリーする時は選択ボックスになります。是非このページを参考にしてください。
https://docs.djangoproject.com/ja/3.0/ref/models/fields/#choices
db_columnフィールドのデータベースのカラムの名前を指定します。与えなければフィールド名になります。
db_indexTrueの場合インデックスがこのフィールドに生成されます。
db_tablespaceデータベースのテーブルスペースの名前(索引がある場合) 。デフォルトでは、プロジェクトのDEFAULT_INDEX_TABLESPACE設定(設定されている場合)またはdb_tablespaceで指定できます。このオプションはバックエンドが索引のテーブルスペースを支持しない場合無視されます。https://qiita.com/nachashin/items/f768f0d437e0042dd4b3
defaultフィールドのデフォルト値です。特定の値又は呼び出し可能オブジェクトを渡すことができます。もし渡した値が呼び出し可能であれば新しくオブジェクトが生成される度に呼び出されます。
editableFalseにするとadmin又はModelFormに表示されません。デフォルトはTrueです。
error_messageserror_messagesはフィールドが送るデフォルトのメッセージ をオーバライドできます。オーバライドしたいメッセージに対応する文字列をキー とし、メッセージを値に持つ辞書を渡してください。
help_textフォームウィジェットなどに表示するヘルプテキストになります。
primary_keyTrueの場合モデルの主キーになります。指定しない場合Autofieldが自動に追加され主キーになります。Trueの場合null=False、unique=Trueになります。
uniqueTrueの場合テーブルの中で同じ値は設定できません。同じ値を入れようとした場合保存する時にエラーがでます。
unique_for_dateDateFieldやDateTimeField型のフィールドの名前になります。
そのフィールドの名前は独特な値になります。(他の名前と同じになる事はありません。)
unique_for_monthフィールドの名前は月毎に独特になります。
unique_for_yearフィールドの名前は年毎に独特になります。
verbose_nameadminで表示されるときの名前。指定しない場合フィールドの名前で生成されます。(_を半角スペースに変えるなど加工は自動でする。)
validators実行するバリデータのリスト。https://docs.djangoproject.com/ja//3.0/ref/validators/

参考: フィールドオプション

モデルの書き込み

では実際にデータベースにテーブルを入れる準備をしてみましょう。

今回は個人情報管理アプリを作ってみましょう。

個人情報は以下になります。

  • 姓–Last Name
  • 名–First Name
  • 性別–Gender
  • 年齢–Age
  • 誕生日–Birthday
  • メールアドレス–E-mail

ではmysite/hello/models.pyを以下の様に編集してデータベースへテーブルを反映する準備をします。

from django.db import models

# Create your models here.
class Personinfo(models.Model):
    GENDER = [
        ('Male','Male'),
        ('Female','Female'),
    ]
    last_name = models.CharField(max_length=30)
    first_name = models.CharField(max_length=30)
    gender = models.CharField(max_length=10,choices=GENDER)
    age = models.IntegerField(default=0)
    birthday = models.DateField()
    email = models.EmailField()

これで準備を完了しました。次はデータベースに今作ったテーブルを反映させます。

モデルのmigrate/makemigrations

次は先ほど作成したテーブルを反映させる方法を紹介します。

反映するために二つのコマンドを知る必要があります。

コマンドは以下になります。

  • makemigrationsマイグレーションファイルを作成します。(マイグレーションファイルはモデルの変更をパッケージングする。)
  • migrateはデータベースにmodels.pyで作ったテーブルを反映させます。(マイグレーションのモデルの変更パッケージを適応する。)

参考:migrate/makemigrations

では実際にマイグレーションファイルを作り適応しましょう。

mysite/ディレクトリに行き以下のコマンドを打ちます。

python manage.py makemigration
# Migrations for 'hello':
  # hello/migrations/0001_initial.py
    # - Create model Personinfo

その後以下のコマンドを打ちます。

python manage.py migrate
# Operations to perform:
  # Apply all migrations: admin, auth, contenttypes, hello, sessions
# Running migrations:
  # Applying hello.0001_initial... OK

これで反映完了です。 反映前のデータベースは以下です。

+----------------------------+
| Tables_in_mysite_sample    |
+----------------------------+
| auth_group                 |
| auth_group_permissions     |
| auth_permission            |
| auth_user                  |
| auth_user_groups           |
| auth_user_user_permissions |
| django_admin_log           |
| django_content_type        |
| django_migrations          |
| django_session             |
+----------------------------+
10 rows in set (0.00 sec)

反映後のデータベースは以下です。

+----------------------------+
| Tables_in_mysite_sample    |
+----------------------------+
| auth_group                 |
| auth_group_permissions     |
| auth_permission            |
| auth_user                  |
| auth_user_groups           |
| auth_user_user_permissions |
| django_admin_log           |
| django_content_type        |
| django_migrations          |
| django_session             |
| hello_personinfo           |
+----------------------------+
11 rows in set (0.00 sec)
よかったらシェアしてね!
  • URLをコピーしました!
目次