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.