View on GitHub

モデルの定義

Home

モデルの定義

モデルの定義

src/backend/api/online/models.py

from django.db import models
from django.contrib.postgres.indexes import GinIndex  # <- 追加
from .utils import encrypt, hash, decrypt, mask_email
import uuid
......
# ↓追加
class Movie(models.Model):
    """
    映画モデル

    Attributes
    ----------
    movie_id : IntegerField
        映画ID
    title : TextField
        タイトル
    year : IntegerField
        公開年
    genres : ManyToManyField[Genre]
        ジャンルリスト
    imdb_id: IntegerField
        IMDb ID
    tmdb_id: IntegerField
        TMDB ID
    """
    movie_id = models.IntegerField(primary_key=True)
    title = models.TextField(blank=False, null=False)
    year = models.IntegerField(blank=True, null=True)
    imdb_id = models.IntegerField(blank=True, null=True)
    tmdb_id = models.IntegerField(blank=True, null=True)

    class Meta:
        managed = True
        db_table = 'm_movies'
        indexes = [
            GinIndex(fields=['title'], name='movie_title_gin', opclasses=['gin_trgm_ops']),
        ]

    def __str__(self):
        return f'Movie {self.movie_id}: {self.title}'


class Genre(models.Model):
    """
    ジャンルモデル

    Attributes
    ----------
    genre_id : IntegerField
        ジャンルID
    genre_name : TextField
        ジャンル名
    """
    genre_id = models.IntegerField(primary_key=True)
    genre_name = models.TextField(blank=False, null=False)

    class Meta:
        managed = True
        db_table = 'm_genres'

    def __str__(self):
        return f'Genre {self.genre_id}: {self.genre_name}'


class MovieGenre(models.Model):
    """
    映画-ジャンル中間モデル

    Attributes
    ----------
    id : CharField
        ID
    movie : ForeignKey[Movie]
        映画
    genre : ForeignKey[Genre]
        ジャンル
    """
    id = models.CharField(primary_key=True, max_length=9)
    movie = models.ForeignKey(Movie, on_delete=models.CASCADE, related_name='movie_genres')
    genre = models.ForeignKey(Genre, on_delete=models.CASCADE, related_name='genre_movies')

    class Meta:
        managed = True
        db_table = 'm_movies_genres'

    def __str__(self):
        return f'MovieGenre {self.id}: Movie {self.movie.title} - Genre {self.genre.genre_name}'
# ↑追加

マイグレーション

(recsys_full) backend$ python manage.py makemigrations online
Migrations for 'online':
  api/online/migrations/0002_genre_movie_moviegenre.py
    + Create model Genre
    + Create model Movie
    + Create model MovieGenre

(recsys_full) backend$ python manage.py migrate
Operations to perform:
  Apply all migrations: accounts, admin, auth, contenttypes, online, sessions, token_blacklist
Running migrations:
  Applying online.0002_genre_movie_moviegenre... OK

テーブルの確認

recsys_full=# \dt
                       List of relations
 Schema |                 Name                 | Type  | Owner
--------+--------------------------------------+-------+-------
...(略)...
 public | m_genres                             | table | rsl
 public | m_movies                             | table | rsl
 public | m_movies_genres                      | table | rsl
 public | t_users                              | table | rsl
...(略)...
(16 rows)

recsys_full=# \d m_movies
               Table "public.m_movies"
  Column  |  Type   | Collation | Nullable | Default
----------+---------+-----------+----------+---------
 movie_id | integer |           | not null |
 title    | text    |           | not null |
 year     | integer |           |          |
 imdb_id  | integer |           |          |
 tmdb_id  | integer |           |          |
Indexes:
    "m_movies_pkey" PRIMARY KEY, btree (movie_id)
    "movie_title_gin" gin (title gin_trgm_ops)
Referenced by:
    TABLE "m_movies_genres" CONSTRAINT "m_movies_genres_movie_id_1b16046f_fk_m_movies_movie_id" FOREIGN KEY (movie_id) REFERENCES m_movies(movie_id) DEFERRABLE INITIALLY DEFERRED

recsys_full=# \d m_genres
                Table "public.m_genres"
   Column   |  Type   | Collation | Nullable | Default
------------+---------+-----------+----------+---------
 genre_id   | integer |           | not null |
 genre_name | text    |           | not null |
Indexes:
    "m_genres_pkey" PRIMARY KEY, btree (genre_id)
Referenced by:
    TABLE "m_movies_genres" CONSTRAINT "m_movies_genres_genre_id_c12f6107_fk_m_genres_genre_id" FOREIGN KEY (genre_id) REFERENCES m_genres(genre_id) DEFERRABLE INITIALLY DEFERRED


recsys_full=# \d m_movies_genres
                  Table "public.m_movies_genres"
  Column  |         Type         | Collation | Nullable | Default
----------+----------------------+-----------+----------+---------
 id       | character varying(9) |           | not null |
 genre_id | integer              |           | not null |
 movie_id | integer              |           | not null |
Indexes:
    "m_movies_genres_pkey" PRIMARY KEY, btree (id)
    "m_movies_genres_genre_id_c12f6107" btree (genre_id)
    "m_movies_genres_id_c224af9e_like" btree (id varchar_pattern_ops)
    "m_movies_genres_movie_id_1b16046f" btree (movie_id)
Foreign-key constraints:
    "m_movies_genres_genre_id_c12f6107_fk_m_genres_genre_id" FOREIGN KEY (genre_id) REFERENCES m_genres(genre_id) DEFERRABLE INITIALLY DEFERRED
    "m_movies_genres_movie_id_1b16046f_fk_m_movies_movie_id" FOREIGN KEY (movie_id) REFERENCES m_movies(movie_id) DEFERRABLE INITIALLY DEFERRED

参考

  1. 株式会社オープントーン,佐藤大輔,伊東直喜,上野啓二,『実装で学ぶフルスタック Web 開発 エンジニアの視野と知識を広げる「一気通貫」型ハンズオン』,翔泳社,2023.
    • 4-3 バックエンド(API)とフロントエンド(画面)の連携
    • 6-3 バックエンドでモデルを作成する
  2. 横瀬明仁,『現場で使える Django の教科書《基礎編》』,2018.
    • 第 6 章 モデル (Model)