概要(Django のモデル=「DBテーブルを Python クラスとして扱う仕組み」)
Django の「モデル」は一言でいうと、
「データベースのテーブルを、Python のクラスとして表現したもの」
です。
もっとくだけて言うと、
本当は SQL でゴリゴリやるところを、
「Python のクラスのインスタンスを作る/保存する」だけで済ませるための仕組み
です。
Django には ORM(Object Relational Mapper)という機能が入っていて、
モデルを書くだけで、
テーブルを自動で作る
データの追加・更新・削除・検索を Python だけで書ける
という世界になります。
ここから、初心者向けに
モデルとは何か
モデルの定義の仕方(フィールド、型、主キー)
マイグレーションの考え方
基本的な CRUD 操作(作る・読む・更新・削除)
リレーション(外部キー)のイメージ
を、例を交えてじっくり解説します。
Django モデルの「全体像」をイメージする
モデルは「1テーブル=1クラス」が基本
Django では、データを保存したいとき、まず「モデルクラス」を作ります。
例えば「本(Book)」を管理する小さなアプリなら、
こんなモデルを考えます。
from django.db import models
class Book(models.Model):
title = models.CharField(max_length=200)
price = models.IntegerField()
published_at = models.DateField(null=True, blank=True)
Pythonここで Book クラスが「モデル」です。
Book は、データベースの中では book というテーブル(正確には app名_book)になります。
Book の 1 レコード(行)は、
Python では Book クラスの 1 インスタンスとして扱われます。
「テーブルの 1 行= Book の 1 オブジェクト」という対応を押さえてください。
models.Model を継承するだけで「ORM の対象」になる
すべての Django モデルは models.Model を継承します。
class Book(models.Model): と書いた瞬間、このクラスは
データベーステーブルとの橋渡し役
ORM の操作対象
になります。
Django は、このクラス定義を読み込んで、
どんなテーブルを作るべきか
どんなカラム(列)が必要か
を理解します。
フィールド定義(title = models.CharField(...) など)が、
そのままテーブルの列定義になります。
フィールド(Field)と主キー(Primary Key)の基本
フィールドは「列の型」と「制約」を表す
先ほどの Book モデルをもう一度見てみます。
class Book(models.Model):
title = models.CharField(max_length=200)
price = models.IntegerField()
published_at = models.DateField(null=True, blank=True)
Pythonここで重要なのは、それぞれが
title → 文字列(最大200文字)
price → 整数
published_at → 日付(null も許す)
という「列の型と制約」を表していることです。
CharField、IntegerField、DateField のようなクラスが、
Django でいう「フィールド(Field)」です。
例えば CharField(max_length=200) は、
「この列は文字列で、最大長は200文字まで」という意味になります。
null=True は「DBレベルでは NULL を許す」、blank=True は「フォームなどで空でもOK」という意味です(微妙に違いますが、初心者のうちはセットで覚えてOKです)。
主キー(id)は書かなくても自動で付く
モデルを書くときに、id を自分で定義していないのに、
なぜか id というフィールドが現れることに気づくと思います。
class Book(models.Model):
title = models.CharField(max_length=200)
Pythonこれだけ書いてマイグレーションをすると、
id(AutoField: 自動採番の整数)
title(CharField)
という 2 列ができあがります。
Django は、明示的に主キーを定義しない場合、
自動で id という主キーを追加してくれます。
自分で主キーを定義したいときは、
class Book(models.Model):
code = models.CharField(max_length=20, primary_key=True)
title = models.CharField(max_length=200)
Pythonのように primary_key=True を付けますが、
基本的には自動の id を使うのがシンプルです。
主キーは「1 行を一意に特定するための番号」です。
この id を使って、1 冊の本を指定したりします。
モデルからテーブルを作る流れ(マイグレーション)
「モデルを書いた」だけでは DB にテーブルはまだない
よくある勘違いとして、
「モデルを書いたらテーブルがすぐできる」
と思いがちですが、実際はもう一手間必要です。
Django では、
モデルを書いて保存する
→ 「マイグレーションファイル」を作る
→ そのマイグレーションを実行して、初めて DB が変わる
という流れです。
この「モデルの変更を DB に反映させるための手順」が「マイグレーション」です。
基本コマンドの流れ
Book モデルを書いたあと、ターミナルで次のようにします。
python manage.py makemigrations
python manage.py migrate
makemigrations は、「モデルの変化を検知して、マイグレーションファイルを作る」コマンドです。migrate は、そのマイグレーションを実際に DB に反映させます。
こうすることで、初めて DB に book テーブル(正確には アプリ名_book)が作られます。
大事なポイントは、
モデル = 設計図
マイグレーション = 設計図の変更履歴
migrate = 変更を実際の DB に適用
という関係です。
初心者のうちは、「モデルを変えたら makemigrations → migrate」と覚えておけば OK です。
モデルを使った基本操作(CRUD)を体で覚える
ここからがモデルの「おいしいところ」です。
SQL を書かずに、Python だけでデータ操作ができます。
以降は Django のシェル(python manage.py shell)で試すイメージで説明します。
データを「作る」(Create)
Book の新しいレコードを追加する例です。
from appname.models import Book # 自分のアプリ名に合わせる
book = Book(title="Python入門", price=1500)
book.save()
Pythonこれで、DB に 1 行追加されます。
save() を呼ぶ前の book は、まだ DB に保存されていない「オブジェクト」だけの状態です。save() を呼んだ瞬間、INSERT 文が発行されて DB に保存されます。
もうひとつの書き方として、create() もよく使います。
book = Book.objects.create(title="Django実践", price=2000)
Pythoncreate() は「インスタンスを作って、すぐに save までやる」というショートカットです。
データを「読む」(Read)
全件取得は簡単です。
books = Book.objects.all()
Pythonこれで「Book テーブルの全行」を表す QuerySet(クエリセット)が返ってきます。
実際に中身をリストとして見たいときは list(books) とすれば OK です。
特定条件の行だけ欲しいときは、filter() を使います。
cheap_books = Book.objects.filter(price__lt=1000)
Pythonこれは「price が 1000 未満の Book だけ」を表す QuerySet です。price__lt の __lt は「less than(未満)」の意味です。
主キー(id)で 1 件だけ取りたいときは get() をよく使います。
book = Book.objects.get(id=1)
Python存在しない id を指定すると例外が出るので、その点だけ注意が必要です。
データを「更新する」(Update)
更新は、「取り出して、値を変えて、save」です。
book = Book.objects.get(id=1)
book.price = 1800
book.save()
Pythonこれで id=1 の Book の price が更新されます。
複数行をまとめて更新したいときは、update() もあります。
Book.objects.filter(price__lt=1000).update(price=1000)
Python1000 未満の Book を全部 1000 に底上げする、というようなイメージです。
データを「削除する」(Delete)
削除は、とてもシンプルです。
book = Book.objects.get(id=1)
book.delete()
Pythonまたは、条件に合うものをまとめて削除もできます。
Book.objects.filter(price__lt=500).delete()
Pythonここでのポイントは、
SQL を一切意識せず、
「Python オブジェクト」としてデータを扱える
ということです。
これが Django モデル+ORM の一番のメリットです。
リレーション(外部キー)を使ってモデル同士をつなぐ
「本」と「著者」の関係を例にする
モデルの真価は、「モデル同士をつなぐ」ことで発揮されます。
例えば、「著者(Author)」と「本(Book)」の関係を考えてみます。
1人の著者は複数の本を書く
1冊の本は 1人の著者を持つ
これは「1 対 多」の関係です。
Django では、外部キー(ForeignKey)でこれを表現します。
class Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
title = models.CharField(max_length=200)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
PythonBook に author = models.ForeignKey(Author, ...) と書くことで、
Book テーブルに「author_id」という列ができます。
これは DB レベルでは、「Author テーブルの id を参照する外部キー」です。
モデルから見ると「author は Author のインスタンス」になる
Python から見ると、Book の author フィールドは
単なる数値(author_id)ではなく、「Author オブジェクト」に見えます。
例えば、
a = Author.objects.create(name="山田太郎")
b = Book.objects.create(title="Django入門", author=a)
Pythonとすると、b.author は Author インスタンス a になります。
b.author.name # → "山田太郎"
Python逆に、Author から関連する Book を辿ることもできます。
a_books = a.book_set.all()
Pythonbook_set という「逆参照」が自動で生えます(カスタマイズも可能)。
リレーションのイメージは、
テーブルの世界(DB)では id 同士がつながっている
Python の世界(Django モデル)では「オブジェクト同士がつながっている」
という感覚です。
これを意識すると、外部キーが一気に理解しやすくなります。
まとめ(Django のモデルは「DB のめんどくささを隠してくれる窓口」)
Django のモデルを、初心者目線で整理するとこうなります。
モデルは models.Model を継承したクラスで、「1 クラス=1 テーブル」「1 インスタンス=1 行」という対応になっている。
フィールド(CharField, IntegerField, DateField など)が、テーブルの列の型や制約を表し、主キー id は明示しなければ自動で付く。
モデルを書いたあと、「makemigrations → migrate」で初めて DB にテーブルが作られ、以降もモデル変更はマイグレーションとして DB に反映していく。Book.objects.create(...)、Book.objects.filter(...)、book.save()、book.delete() などの ORM 操作で、SQL を書かずに CRUD ができる。
ForeignKey などを使ってモデル同士をつなぐことで、「オブジェクト同士がリンクしている」感覚でリレーションを扱える。

