## 概要 [[Django]]の `models.Model` における挙動を確かめるため、実際に動かしてみてまとめたレポート。環境は以下とほぼ同じ。 <div class="link-card-v2"> <div class="link-card-v2-site"> <img class="link-card-v2-site-icon" src="https://publish-01.obsidian.md/access/35d05cd1bf5cc500e11cc8ba57daaf88/favicon-64.png" /> <span class="link-card-v2-site-name">Minerva</span> </div> <div class="link-card-v2-title"> 📜2025-09-24 Django REST frameworkを学習してみる </div> <div class="link-card-v2-content">仕事でDjango REST frameworkを使う必要が生じ、機能が多く把握しきれなかったため、Django 4.2とDRF 3.16.1を用いて体系的な学習を開始した。環境構築では依存関係やバージョン選定、PostgreSQL導入、psycopg3の利用などに取り組み、SerializerやModelSerializerの実装、APIエンドポイント作成、Brunoによる動作確認までを段階的に実施した。</div> <img class="link-card-v2-image" src="https://publish-01.obsidian.md/access/35d05cd1bf5cc500e11cc8ba57daaf88/Notes/attachments/activity.webp" /> <a data-href="📜2025-09-24 Django REST frameworkを学習してみる" class="internal-link"></a> </div> %%[[📜2025-09-24 Django REST frameworkを学習してみる]]%% ### 環境 | 対象 | バージョン | | ------------------------- | ---------- | | [[macOS]] | 15.7.1 | | [[Python]] | 3.13.7 | | [[Django]] | 4.2 | | [[Django REST framework]] | 3.16.1 | | [[psycopg3]] | 3.2.10 | | [[PostgreSQL]] | 18.0.1 | ## CASCADE ### 準備 `models.py` ```python class Human(models.Model): id = models.CharField(primary_key=True) name = models.CharField(max_length=100) class Animal(models.Model): id = models.CharField(primary_key=True) name = models.CharField(max_length=100) owner = models.ForeignKey(Human, on_delete=models.CASCADE, related_name="pets") ``` `debug.py` ```python from drf_slack_notification.main.models import Animal, Human def insert(): tadashi = Human(id="tadashi", name="タダシ") tadashi.save() mimizou = Animal(id="mimizou", name="みみぞう", owner=tadashi) mimizou.save() tatsuwo = Animal(id="tatsuwo", name="タツヲ", owner=tadashi) tatsuwo.save() def delete_human(): tadashi = Human.objects.get(id="tadashi") tadashi.delete() def delete_animals(): mimizou = Animal.objects.get(id="mimizou") mimizou.delete() tatsuwo = Animal.objects.get(id="tatsuwo") tatsuwo.delete() ``` ```console $ python manage.py shell import drf_slack_notification.main import debug debug.insert() ``` ### スクリプトから削除 - 親を削除すると子も削除される - 親がいても子は削除できる #### 親を消す ```console debug.delete_human() ``` `tadashi` は削除でき、`tatsuwo` と `mimizou` も連動して消える。期待通りの挙動。 #### 子を消す ```console debug.delete_animals() ``` `tatsuwo` と `mimizou` は削除されるが、親である `tadashi` はそのまま。 ### DBから削除 - 子がいると親は削除できない - 親がいても子は削除できる #### 親を消す `tadashi` を削除しようとしたら以下のエラーになった。 ```error Error synchronizing data with database Reason: SQL Error [23503]: ERROR: update or delete on table "main_human" violates foreign key constraint "main_animal_owner_id_c1f0dd8e_fk_main_human_id" on table "main_animal" Detail: Key (id)=(tadashi) is still referenced from table "main_animal". ``` `mimizou` と `tatsuwo` から参照されているためと思われる。CASCADEを設定してもDBからの操作ではエラーになるらしい。 #### 子を消す `mimizou` と `tatsuwo` を削除してからなら `tadashi` を削除できた。