97

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?

3
  • 3
    Possible duplicate of How to add column in ManyToMany Table (Django)
    – ravi404
    Oct 22, 2015 at 6:23
  • @ravz Why shouldn't that one be closed as a dupe of this one, instead?
    – TylerH
    Oct 22, 2015 at 18:50
  • @TylerH this is an older post. However both the questions have answers , i'd suggest merging these.
    – ravi404
    Oct 26, 2015 at 8:45

1 Answer 1

138

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)
8
  • 4
    How can I access the date_joined in a template?Group.date_joined does not work.
    – Timo
    Aug 31, 2014 at 13:18
  • 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():
    – gruszczy
    Sep 1, 2014 at 4:48
  • 2
    How can I use group.members.add() with the above approach?
    – Dejell
    Mar 5, 2017 at 8:07
  • @Dejell the code samples in the link mentioned might help you. Apr 6, 2017 at 9:56
  • 2
    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.
    – Sensei
    Mar 14, 2018 at 2:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.