Django REST Frameworkでは手軽にFKを設定することができますが、何も指定しないとPK(ID)に対してFKが設定されます。これをPK以外のカラムに対してFKを設定する方法です。
今回は次のような社員とその社員の所属部署を表すテーブルを考えます。
from django.db import models
class User(models.Model):
name = models.CharField(max_length=100)
class UserOrg(models.Model):
user_org = models.CharField(max_length=100)
is_main = models.BooleanField(default=True)
user_id = models.ForeignKey(User, related_name='UserOrgs', on_delete=models.CASCADE)
これをマイグレーションすると次のテーブルができます。
| id | name |
|---|---|
| 1 | 佐藤 |
| 2 | 鈴木 |
| 3 | 高橋 |
| id | user_id | org_name | is_main |
|---|---|---|---|
| 1 | 1 | 営業部 | true |
| 2 | 2 | 開発部 | true |
| 3 | 3 | 管理部 | true |
| 4 | 3 | 経理部 | false |
データがあった方が分かりやすいので、適当に追加しました。
1つの部署にしか所属していない人もいれば、複数の部署に所属(兼務)している人もいますね。
こんな感じでModelにmodels.ForeignKey…と定義するとDjangoではPK(ID)に対して自動的にFKを設定してくれます。
ただ、これだとuser_orgテーブルだけ見たとき営業部に所属しているuser_idカラムが1の人って誰?ってなりますよね。
これを避けるため、次のようにUserにコードをつけておき、そのコードでFKを設定することを考えます。
| id | code | name |
|---|---|---|
| 1 | sato | 佐藤 |
| 2 | suzuki | 鈴木 |
| 3 | takahashi | 高橋 |
| id | user_code | org_name | is_main |
|---|---|---|---|
| 1 | sato | 営業部 | true |
| 2 | suzuki | 開発部 | true |
| 3 | takahashi | 管理部 | true |
| 4 | takahashi | 経理部 | false |
こうすることで、user_orgテーブルだけ見たときに、user_codeカラムを見ればどの社員かわかりますよね。
これをDjango REST Frameworkでやりたい場合、次のようにForeignKeyに対してdb_columnとto_fieldを設定するとできます。
from django.db import models
class User(models.Model):
code = models.CharField(max_length=100, unique=True) # FKを設定するカラムはユニークにする必要がある
name = models.CharField(max_length=100)
class UserOrg(models.Model):
user_org = models.CharField(max_length=100)
is_main = models.BooleanField(default=True)
user = models.ForeignKey(User, db_column='user_code', to_field='code', related_name='UserOrgs', on_delete=models.CASCADE) # db_columnにUserOrgのカラム名、to_fieldにFK先のカラム名を指定する
PK以外のカラムに対してFKを設定する方法でした。