jason
jason

Reputation: 3075

ManyRelatedManager object is not iterable

Trying to do this:

wishList = WishList.objects.get(pk=20)
matches = [val for val in Store.attribute_answers.all() if val in wishList.attribute_answers]

And get this...

'ManyRelatedManager' object is not iterable

Both fields are many-to-many so how can this be done?

Upvotes: 144

Views: 141050

Answers (7)

Mohamed Stohy
Mohamed Stohy

Reputation: 53

Answers are good and I just needed to add a point for easier understanding.You couldn't query the field where many to many is set because it returns and objects not a list of options.It is better to get the data from the field in your views then pass it to the templates.For example if you have posts model where each post has many to many relations with Tags model.

class Tag(models.Model):
      ""
class Post(models.Model):
      tags = models.ManyToManyField(Tag)

If you tried post.tag.caption it will return this error.You should pass tags as a seperate idintifier in your views.

"post": identified_post,
"post_tags":identified_post.tags.all()

instead of passing only

"post": identified_post

Upvotes: 0

Qback
Qback

Reputation: 4918

all()

For everyone who finds reading code in questions as TL;DR

Instead of query_set.many_to_many

you should use query_set.many_to_many.all()

Upvotes: 51

second
second

Reputation: 28665

Sounds like you are looking for something like

Store.attribute_answers.all()

Upvotes: 80

andyw
andyw

Reputation: 3783

If you are doing this in a template:

{% for room in study.room_choice.all %}
  {{ room }}
  {% empty %}
  empty list!
{% endfor %}

UPDATE

If you have a through table, you can access the elements in that table (as detailed here) like so (note, you use the through table name, in lowercase, suffixing _set):

{% for roominfo in participant.roomchoicethru_set.all %}
  {{ roominfo.room}} {{ roominfo.telnumber}}
{% endfor %}

Upvotes: 61

Aidan Ewen
Aidan Ewen

Reputation: 13328

Try

matches = [val for val in Store.attribute_answers.all() if val in WishList.attribute_answers.all()]

Notice the parenthesis at the end of WishList.attribute_answers.all(). Adding the parenthesis invokes the all function to return an iterable.

If you include the parenthesis you're saying "give me all the values in the stores answers so long as that value is also in the wish lists answers". Without the parenthesis you're asking for all the values from the store's answers that are also in the all function, which is meaningless. The all function is not an iterable (it's a function that returns an iterable)

Upvotes: 162

Alex Tomlinson
Alex Tomlinson

Reputation: 19

I keep hitting this question whenever this problem comes up. Particularly when trying to actually iterate over a manytomany in a function.

As a template you can do:

array = many_to_many.all()
for x in many_to_many:
  function here

Upvotes: 0

Nids Barthwal
Nids Barthwal

Reputation: 2419

Here busines_type is foreign_key in profile model

pro = Profile.object.filter(user=myuser).first()
business_type = pro.business_type.all()
if business_type:
    b_type = ''
    for b in business_type:
        b_type += str(b.type)+' '
        a = b_type

Upvotes: -3

Related Questions