やる気がストロングZERO

やる気のストロングスタイル

Django カスタムカラムを含んだ多対多モデルの書き方

Djangoだと多対多の中間テーブルを自動的に作成してくれるが、この中間テーブルになにかデータをもたせたい場合がある。
その場合は以下のような定義をしないといけない。

モデル定義

class Person(models.Model):
    name = models.CharField(max_length=128)

    def __str__(self):
        return self.name


class Group(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField(Person, through='Membership')

    def __str__(self):
        return self.name


class Membership(models.Model):
    person = models.ForeignKey(Person, on_delete=models.CASCADE)
    group = models.ForeignKey(Group, on_delete=models.CASCADE)
    date_joined = models.DateField()
    invite_reason = models.CharField(max_length=64)

データ登録

ringo = Person.objects.create(name="Ringo Starr") #Person:ringoがDB上にも作成される
paul = Person.objects.create(name="Paul McCartney") #Person:paulがDB上にも作成される
beatles = Group.objects.create(name="The Beatles”) #Group:beatlesがDB上にも作成される

m1 = Membership(person=ringo, group=beatles, date_joined=date(1962, 8, 16), invite_reason="Needed a new drummer.") #ringoとbeatlesの関連が作成される(DBにはまだ作成されない)
m1.save() # この時点でDB上にも作成される

Membership.objects.create(person=paul, group=beatles, date_joined=date(1960, 8, 1), invite_reason="Wanted to form a band.") #paulとbeatlesの関連がDB上にも作成される

データ表示

beatles.members.all()

データ削除

beatles.members.remove(ringo)