LoginSignup
2
4

More than 1 year has passed since last update.

Djangoでdatabaseのviewを使う方法

Posted at

なぜ使用するのか

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を使用することができます。

以上になります。

参考記事

2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4