Saturnix
Saturnix

Reputation: 10564

django .filter (or any other manager function) to check if item is present in ManyToMany field

class Barrack(models.Model):
    """
    ... many other fields ...
    """

    def how_many_helmets_for_this_user(self, user):
        helmets = self.helmet_set.filter(possessors__contains=user) # how do we do this?
        return helmets.count()

class Helmet(models.Model):
    barrack = models.ForeignKey(Barrack)
    possessors = models.ManyToManyField(User)

The code above doesn't works. The __contains filter is made only for strings. Yet, I'd like to filter all the helmets where user is in helmet.possessors.

I'd like to know if this is possible to do so using exclusively Django's managers function.


I already have a lousy and extremely inefficient solution which doesn't use Django's manager:

def how_many_helmets(self, user):
    result = 0
    helmets = self.helmet_set.all()
    for helmet in helmets:
        if helmet.is_user_in_possessors(user):
            result += 1
    return result

# in Helmet class
def is_user_in_possessors(self, user):
    for possessor in self.possessors.all():
        if possessor == user:
            return True
    return False

Upvotes: 0

Views: 29

Answers (1)

Gocht
Gocht

Reputation: 10256

Try:

helmets = self.helmet_set.filter(possessors=user)

Here you will find the relevant documentation for M2M relationships

Upvotes: 1

Related Questions