Reputation: 2817
I stumbled upon (for me, at least) some rather odd behaviour in Django. I'm not sure if this is supported/allowed behaviour.
Suppose I have the following model:
class Club
name = CharField(....)
memberships = models.ManyToManyField(Person, through=ClubMembership, related_name='clubs')
def getMembership(self, personID):
return ClubMembership.objects.get(club_id=self.id, person_id=personID)
Obviously, getMembership
returns the associated ClubMembership
instance (For now, let's assume we only call this method for persons that are in fact in the club).
Now, when calling this method, I found that:
club = Club.objects.get(...)
person = Person.objects.get(...)
membership = club.getMembership(person)
and
club = Club.objects.get(...)
person = Person.objects.get(...)
membership = club.getMembership(person.id)
are both yielding the correct membership. Is there some magic happening inside the filter
/get
methods that check if the passend keyword (for person_id
) is in fact an integer (pk) or a model instance?
If both is valid and allowed, what are the implications? Any differences performance wise? Which would be the preferred method?
Ofc I could filter against the entire person model and not just the id, like so:
def getMembership(self, person):
return ClubMembership.objects.get(club_id=self.id, person=person)
But afaik, this would be a lot slower, right?
Upvotes: 4
Views: 736
Reputation: 2402
As stated in Queries over related objects section of documentation there's no difference between an integer (pk) or a model instance.
In their example, if you have a Blog object b with id=5, the following three queries would be identical:
Entry.objects.filter(blog=b) # Query using object instance
Entry.objects.filter(blog=b.id) # Query using id from instance
Entry.objects.filter(blog=5) # Query using id directly
Upvotes: 5