Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django - reverse lookups with ManyToManyField

I'm trying to follow the code from the django docs:

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

    def __unicode__(self):
        return self.name

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

    def __unicode__(self):
        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)


>>> ringo = Person.objects.create(name="Ringo Starr")
>>> paul = Person.objects.create(name="Paul McCartney")
>>> beatles = Group.objects.create(name="The Beatles")
>>> m1 = Membership(person=ringo, group=beatles,
...     date_joined=date(1962, 8, 16),
...     invite_reason= "Needed a new drummer.")
>>> m1.save()
>>> beatles.members.all()
[<Person: Ringo Starr>]
>>> ringo.group_set.all()

My model looks like this:

class Trip(models.Model):
    members = models.ManyToManyField(User,blank=True,null=True,through='TripReservation')

But when I call user.group_set.all() for a given user instance, I get an error that there is no attribute group_set

like image 891
JPC Avatar asked Feb 03 '11 01:02

JPC


1 Answers

First, are you using a through Model? You have through in there, but you don't have it listed. If you aren't you don't need it.

I would add a related_name, like so:

class Trip(models.Model):
    members = models.ManyToManyField(User,blank=True,null=True, related_name='user_trips')

Then you should be able to call:

user.user_trips.all()

I called it 'user_trips' rather than 'trips' becuase if it isn't a unique name it can cause conflicts.

If you are using a through Model, it would look more like this:

#User is defined in django.auth

class Trip(models.Model):
    members = models.ManyToManyField(User,blank=True,null=True, related_name='user_trips', through='TripReservation')

class TripReservation(models.Model):
    user = models.ForeignKey(User)
    trip = models.ForeignKey(Trip)
    registered = models.DateField()

Understand that with this way, the TripReservation refers to a particular Users reservation to the Trip, not the whole trip, and information about the trip should be properties on the Trip model itself. So, TripReservation.registered, is when that particular user registered for the trip.

The user trips lookup would be the same:

user.user_trips.all()
like image 168
MattoTodd Avatar answered Oct 04 '22 06:10

MattoTodd