0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Django Modelで複合キーを利用する

Last updated at Posted at 2025-01-31

Django ModelのPRIMARY KEY

Djangoで新たにテーブル設計をする際には、基本的にはサロゲートの単一キーとすることをお勧めします。Django自体がその前提で設計されたフレームワークだからです。
ただし既存システムの場合はすでに複合キーが設定されていることもあると思うので、この場合は別途対策が必要です。

django-compositepk-model

from django.db import models
from cpkmodel import CPkModel

class Staff1(CPkModel):
    company_code = models.CharField(max_length=9, primary_key=True)
    staff_number = models.IntegerField(primary_key=True)
    text1 = models.CharField(max_length=255, blank=True, null=True)
    text2 = models.CharField(max_length=255, blank=True, null=True)

    class Meta:
        managed = False
        db_table = "Staff"
        constraints = [
            models.UniqueConstraint(fields=["company_code", "staff_number"], name="primary_key")
        ]

多くの問題はこちらを利用すれば解決する。
ただしadmin機能を利用する場合には、問題がある。

Add(Create) has a problem that CreateView do unique check to each key Field. So you can't add enough child records.

つまり、新規登録を行う際には一意チェックが期待通り作用しないのである。

viewflow

上記を解決するためにはviewflowを利用してModelを作成する。

from django.db import models
from viewflow.fields import CompositeKey

class Staff2(models.Model):
    id = CompositeKey(columns=["company_code", "staff_number"])
    company_code = models.CharField(max_length=9)
    staff_number = models.IntegerField()
    text1 = models.CharField(max_length=255, blank=True, null=True)
    text2 = models.CharField(max_length=255, blank=True, null=True)

    class Meta:
        managed = False
        db_table = "Staff"

まとめ

以上のように、Djangoにて複合キーを利用する場合は注意が必要である。
Modelは一つのテーブルに対して複数用意しても問題ないので、状況に応じて使うと良いかもしれない。

0
1
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
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?