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