The Django Through relationship is, in my opinion, one of the most powerful things you can do with Django. It allows you to define extra information about a database level relationship. In this blog post, we will look at building the Models for a “Through” relationship.
Example Context: Lets say you have a Person class and an Event class. Now you want to have people be able to RSVP to Events. In this case, the RSVP will be the Intermediary Model that links a Person to an Event and stores extra information about the link. Here is what the classes would look like:
class Person(models.Model): name = models.CharField(max_length=200) image = models.ImageField(upload_to="person_images", blank=True) RSVPList = models.ManyToManyField(Event, through='RSVP') def __unicode__(self): return self.name class Event(models.Model): name = models.CharField(max_length=200) date = models.DateTimeField() def __unicode__(self): return self.name class RSVP(models.Model): person = models.ForeignKey(Person) event = models.ForeignKey(Event) attending = models.CharField(max_length=20, default='maybe') def __unicode__(self): return self.attending
The Event class is autonomous, it doesn’t have a relationship to anything, and exists solely to hold information that defines events.
The Person class has a ManyToMany relationship to Event. This allows a single Person to RSVP to multiple Events. RSVPList will provide a list of all the Events a single Person object has RSVP’d to. The magic starts with through=’RSVP’. This tells django that the RSVP class will define extra information about the relationship between a single Person and a single Event.
The RSVP class has a single ForeignKey to a Person object and an Event object, defining a specific relationship between the two objects while enforcing that a single Person can only have one RSVP to any single Event. In the example, we have added the ‘attending’ attribute that will store extra information about the related Person and Event objects. You can add as many extra attributes as you like that define extra information about the individual Person and Event.
The model defines a DB table that functions kind of like this:
[singlepic id=8 w=320 h=240 float=]
Stay tuned, in Part 2 I will go over the view code that shows how to instantiate the RSVP object and attach it to a Person and Event.