Django's ManyToMany Relationship with Additional Fields

48,011

Here is example of what you want to achieve:

http://docs.djangoproject.com/en/dev/topics/db/models/#extra-fields-on-many-to-many-relationships

In case link ever breaks:

from django.db import models

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

    def __str__(self):              # __unicode__ on Python 2
        return self.name

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

    def __str__(self):              # __unicode__ on Python 2
        return self.name

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

Related videos on Youtube

rrb_bbr
Author by

rrb_bbr

Updated on May 15, 2020

Comments

  • rrb_bbr
    rrb_bbr almost 4 years

    I want to store some additional information in that, automatically created, ManyToMany join-table. How would I do that in Django?

    In my case I have two tables: "Employees" and "Projects". What I want to store is how much each of the employees receives per hour of work in each of the projects, since those values are not the same. So, how would I do that?

    What occurred to me was to, instead of the method "ManyToManyField", create explicitly a third class/table to store those new informations and to set its relationship with "Employees" and "Projects" using the "ForeignKey" method. I'm pretty sure it will work, but is this the best approach?

    • ravi404
      ravi404 over 8 years
    • TylerH
      TylerH over 8 years
      @ravz Why shouldn't that one be closed as a dupe of this one, instead?
    • ravi404
      ravi404 over 8 years
      @TylerH this is an older post. However both the questions have answers , i'd suggest merging these.
  • Timo
    Timo over 9 years
    How can I access the date_joined in a template?Group.date_joined does not work.
  • gruszczy
    gruszczy over 9 years
    Group date joined won't work, because Group itself doesn't join anything. Instead, you can get it's members and get their join time. for member in group.members.all():
  • Dejell
    Dejell about 7 years
    How can I use group.members.add() with the above approach?
  • Devesh Khandelwal
    Devesh Khandelwal about 7 years
    @Dejell the code samples in the link mentioned might help you.
  • Sensei
    Sensei about 6 years
    You can access the glue model object with <model>_set. So group.membership_set.all() for example. Note you always lowercase the entire model name to find this attribute and then add _set.
  • Kabali
    Kabali about 4 years
    through='Membership' , it is not creating the table in database. kindly help me.
  • Tristan Brown
    Tristan Brown about 3 years
    Existing ManyToMany fields cannot be altered by adding or removing 'through=', according to the migration exception I just ran into.
  • Tristan Brown
    Tristan Brown about 3 years
    To get around the "M2M fields cannot be altered" exception: stackoverflow.com/questions/26927705/…