なぜ使用するのか
DjangoのQuerysetでjoinや集計関数は使用することができますが、
たくさんテーブルを使用する際にはコードがとても長くなりとても読みづらくなったりします。
そこでDBビューを使用することで、より簡潔に書くことができます。
使用方法
基本のモデル
今回は以下のようなモデルを使用したいと思います!
models.py
class Job(models.Model):
name = models.CharField(max_length=200)
class Charge(models.Model):
amount = models.DecimalField(max_digits=8, decimal_places=2)
month = models.DateField()
job = models.ForeignKey(Job, null=True, blank=True, on_delete=models.PROTECT)
migrationファイルを作成する
python manage.py makemigrations <app_name>
Viewを作成する
migrationファイルを空で作成する
--empty
オプションをつけて実行すると空のマイグレーションファイルが作成されます。
python manage.py makemigrations <app_name> --empty
作成したmigrationファイルに作成するVIEW
を書きます。
# Generated by Django 3.1.7 on 2021-09-29 08:15
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('<app_name>', '0002_auto_20210929_0812'),
]
sql = """
CREATE OR REPLACE VIEW app_chargesummary AS
SELECT row_number() OVER () as id,
ci.job_id,
ci.month
FROM charge ci
GROUP BY ci.job_id, ci.month;
"""
reverse_sql = """
DROP VIEW IF EXISTS app_chargesummary;
"""
operations = [
migrations.RunSQL(sql, reverse_sql),
]
RunSQLの第一引数にmigrate時に実行するSQL、第二引数にロールバックした際のSQLを書きます。
python manage.py migrate <app_name>
マイグレートすることで記載したSQLが実行され、VIEWが作成されます。
VIEWのモデルをかく
作成したVIEWに対応するモデルを記載します。
その際にMetaオプションにmanaged=False
を書くことでマイグレート対象から外れ、
テーブルが作成されずに済みます。
models.py
class ChargeSummary(models.Model):
id = models.BigIntegerField(primary_key=True)
job = models.ForeignKey(Job, on_delete=models.DO_NOTHING)
month = models.DateField()
class Meta:
managed = False
db_table = 'app_chargesummary'
こちらのモデルでall()
やfilter()
などしていただき、
記載したVIEWを使用することができます。
以上になります。
参考記事