🐍

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

2022/11/03に公開約3,200字

モデルとは

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

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

モデル定義

DBテーブル1つにつきModelクラスを一つ作成し、そのクラスのクラス変数としてフィールドを定義する。

以下の例では、ある会社の従業員テーブルPersonと部署テーブルDivisionを定義している。

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 name
1 営業
2 総務
... ...
id name division
1001 alice 2
1002 bob 1
... ... ...

idフィールドはprimary_key=Trueを設定したフィールドが存在しない場合自動で作成される。

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)

その他のクエリ取得メソッドの一覧はこちら

レコードの作成、更新、削除

レコードを作成して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()

QuerySetに対して.deleteで一括削除も可能。詳細はこちら

Model.objectsにはManagerというクラスのインスタンスが入っていて、これを自作してModelに登録することでクエリ取得メソッドの挙動を変えられる 詳細はこちら

Discussion

ログインするとコメントできます