Model編 -- 忙しい人のためのDjango + DjangoRestFramework
モデルとは
DBのテーブル定義とデータの操作を行うクラス。
Modelクラスの1インスタンスがDBの1レコードを表すPythonオブジェクトとなり、PythonコードでDBのデータを扱うことを可能にする。
モデル定義
以下のようなスキーマの部署テーブルDivisionと従業員テーブルPersonを作りたいとする:
Divisionテーブル:
| id | name |
|---|---|
| 1 | Sales |
| 2 | Planning |
| 3 | Development |
| ... | ... |
Personテーブル:
| id | name | division |
|---|---|---|
| 1001 | Alice | 1 |
| 1002 | Bob | 2 |
| ... | ... | ... |
そのためには、以下のようにDBテーブル1つにつきModelクラスを一つ作成し、そのクラスのクラス変数としてフィールドを定義する。
from django.db import models
class Division(models.Model):
name = models.CharField(max_length=30) # 部署名
class Person(models.Model):
id = models.IntegerField(primary_key=True) # 社員番号
name = models.CharField(max_length=30) # 氏名
division = models.ForeignKey("Division", on_delete=models.CASCADE) # 所属部署
Modelクラスはdjango.db.models.Modelクラスを継承して作成。
フィールドはdjango.db.models.XXXFieldのインスタンスとして定義する。
Fieldクラスはデータ型に応じて使い分ける。一覧はこちら
テーブル間のリレーション (ここでは従業員が部署に所属する関係) の定義はいくつか方法があるが、多対一の関係を定義するForeignKeyをよく使う (他の方法はこちら)。第一引数に関係づけるモデル名を文字列で渡す。
idフィールドは、指定がなければ自動で作られ、1始まりの連番が自動付与される (Divisionテーブル参照) 。UUIDなど他のIDを使いたいときは明示的にidフィールドを作成し、primary_key=Trueを設定する (Personテーブル参照) 。
DBのデータ操作
Djangoでは、Modelクラスそのものが1つのデータベーステーブルに対応し、そのModelクラスの1インスタンスが対応するデータベーステーブルの特定のレコードに対応する。
そのため、テーブル自体に対する操作である「クエリの取得」はModelクラス自体で行い、特定のレコードに対する操作である「レコードの作成、更新、削除」はModelのインスタンスで行う。
クエリ取得
DBからクエリを取得するにはModel.objectsのメソッドを呼び出す。
これらのメソッドは大抵QuerySetオブジェクト (Modelインスタンスの配列のようなもの) を返す。その中には個々のレコードを表すModelインスタンスが、取ってきたレコードの件数だけ含まれる。
# Personのインスタンスではなくクラスそのものを操作
all: QuerySet[Person] = Person.objects.all() # 全レコードの取得
newfaces: QuerySet[Person] = Person.objects.filter(id__gte=1500) # id <= 1500で絞り込み
QuerySetにさらにフィルターかけることも可能
all: QuerySet[Person] = Person.objects.all() # 全レコードの取得
newfaces: QuerySet[Person] = all.filter(id__gte=1500)
例外として、レコードを1件だけ取ってくる.get()メソッドはModelインスタンスを直接返す。
bob: Person = Person.objects.get(id=1002)
その他のクエリ取得メソッドの一覧はこちら
取ってきたレコードのフィールド値には、Modelクラスのアトリビュートとしてアクセスできる。
bob: Person = Person.objects.get(id=1002)
Print(bob.id, bob.name) # 1002, Bob
レコードの作成、更新、削除
レコードを作成してDBに保存するには、Modelクラスのインスタンスを作成して.saveメソッドを呼ぶ。
sales: Division = Division.objects.get(name="営業")
new_member = Person(id="1003", name="caro", division=sales) # まだDBには保存されない
new_member.save() # これで保存
オブジェクトの作成と保存を一つの処理で行うには、
create()メソッドを利用してください。
レコードを変更するには、変更したいレコードに対応するModelインスタンスを書き換えて.save()
carol: Person = Person.objects.get(id=1003)
carol.name = "carol"
carol.save()
レコードを削除するには、変更したいレコードに対応するModelインスタンスの.delete()メソッドを呼ぶ
carol: Person = Person.objects.get(id=1003)
carol.delete()
Discussion