## 概要
[[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` を削除できた。