🐍

Model編 -- 忙しい人のためのDjango + DjangoRestFramework

2022/11/04に公開

モデルとは

DBのテーブル定義とデータの操作を行うクラス。

Modelクラスの1インスタンスがDBの1レコードを表すPythonオブジェクトとなり、PythonコードでDBのデータを扱うことを可能にする。

https://docs.djangoproject.com/ja/4.1/topics/db/models/#module-django.db.models

モデル定義

以下のようなスキーマの部署テーブル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