How to filter the Model objects on a field that is a ManyToManyField?

Hi there,

I have a Model and I want to filter it’s objects on a field that is a ManyToManyField.

Let’s say that I have following Model:

class Friend(model.Model):
    freinds = models.ManyToManyField(User)

and I get or create a User object:

user = User.objects.get_or_create(email="[some-email]")

Now I want to filter the Friend Model objects on the ManyToManyField friends using the user as value.

I want something like this:

my_freinds = Friend.objects.filter(user in friends)

How will it be possible?

I want to make sure I’m clear on what you’re looking for here.

Please confirm -

You have an instance of User

Are you looking to retrieve the Friend objects related to that user?

If so, then if the User object is user, it’s user.friends.all() or user.friends.filter(...)

@KenWhitesell yes you are correct, I updated my post to make it more clear so that you don’t get confused.

You told me the reversed way. Look, let me tell again.

I have Friend Model shown above in my question.

I have the instance of User Model as user.

Now I want to retrieve the Friend objects, which have user object in the ManyToManyFeild named friends.

Ok, so given a Friend named friend, you use the automatically-created related object manager, in this case, friend.user_set.all() or friend.user_set.filter(...), etc, to retrieve all the User objects related to friend.

In both cases, the reference to the related model is a model manager. You have all the manager methods available to you on those model managers.

But for some reason, I’m still not sure I understand what you’re looking for. The Friend object doesn’t have a field named friends The friends field in the User object are references to Friend, not User.

What is friend here? An instance of Friend Model?

I don’t want to retrieve User objects, rather I want to retrieve Friend objects.

That’s not the case. I am going to put the code of Friend Model again, so, here it is:

class Friend(model.Model):
    freinds = models.ManyToManyField(User)

I did not put the User Model code because that does not matter as I don’t want to retrieve User objects.

So, let’s say I create a new User object as:

user = User.objects.create(...)

Now, what I want is to retrieve all those Friend objects which have user in their ManyToManyField.

For example, consider that Friend Model does not have ManyToMany but ForeignKeyField, so as in this supposed case, to get all those Friend objects which have user in their ForiegnKeyField, we would do:

user_friends = Friend.objects.filter(friend=user)

So, I want exactly something like this but on ManyToManyField instead of ForiegnKeyField.

I hope you understood now, what I meant.

Ok, I think I’m clear now.

You have a User named user.

You want all Friend that are related to that user.

So you’re looking for Friend.objects.filter(user=user) It works exactly like a reverse ForeignKey relationship.

How will it work? I mean how does the model know that we are looking for Friend objects which are related to user with this line of code Friend.objects.filter(friend=user)?

Does not the friend field have more than one User objects as it is ManyToManyField?

First, note that it’s user=user, not friend=user. The field named user is the reverse reference to the User model. It works like any other reverse ForeignKey reference.

Yes, a Friend may relate to many User. I’m not sure why you think this changes anything.

Read the various docs on ManyToManyField, Many-to-many relationships | Django documentation | Django, and the related object manager docs referenced above - including all the examples to see how they work.

Also, run your tests in the shell, and examine the queries being generated. That should help you understand this.

1 Like

Why it is user=user? The Friend Model does not have any field named user, so how will it work? As you said it’s reverse reference, so if I create the User instance with the name user_one, so in the retrieval statement will it be user_one=user_one or user=user_one?

Read the referenced docs - it’s all explained in there.

OK I studied the docs you referred and here’s a screenshot from the docs:


So, in first and second execution the statements have publications__id and publications__pk. Why they have used double-underscore instead of using a dot like publications.id and publications.pk?

That’s the same notation used anywhere as a parameter. That’s standard Django notation.

If you have a “forward” ForeignKey reference, you use the dot notation as object references (e.g. request.user.username), but the double_underscore if it’s a field reference in a query.