How to return Objects in a Many to Many Django

Asked

Viewed 848 times

2

Consider the model

class Dealership(models.Model):
    dealership = models.CharField(max_length=50)

class Ordered(models.Model):
    customer = models.ForeignKey("Customer")
    dealership = models.ManyToManyField("Dealership")
    status = models.CharField(max_length=2, choices=status_list, default='p')

I tried to

$ ./manage.py shell
>>> from new_way.core.models import Ordered, Dealership
>>> q = Ordered.objects.all()[:5]
>>> [i.dealership for i in q.dealership.all]

Generated the following error:

Traceback (most recent call last):
  File "<console>", line 1, in <module>
AttributeError: 'QuerySet' object has no attribute 'dealership'

How to Return

Ordered.dealership.dealership

all Dealership by Ordered.

1 answer

2


The mistake says 'QuerySet' object has no attribute 'dealership'. You’re actually doing this:

ordens = Ordered.objects.all().dealership.all()

For the code to work properly you must loop the orders and then make a second loop.

lista = []
ordens = Ordered.objects.all()
for ordem in ordens:
    for o in ordem.dealership.all():
        lista.append(o.dealership)

or

lista = [o.dealership for o in ordem.dealership.all() for ordem in Ordered.objects.all()]
  • I didn’t want to mix the posts, but on http://stackoverflow.com/a/30858064/802542 because it doesn’t work the way I did before? Do you have to use 2 loops anyway? But anyway it worked. Thank you.

  • Your code doesn’t work because you were trying to get an attribute from a queryset and not the object, so it was necessary to loop the filtered objects and then another loop of the field objects manytomanyfield

  • a manyTomany always works like this for iteration? Why didn’t I find this in the documentation?

  • 1

    @Regisdasilva always works like this, certainly has in the documentation the explanation, maybe it is not clear.

  • 1

    +1 I would just suggest making a prefetch_related to avoid an additional SQL query for each iteration of this loop (I think the prefetch_related works for ManyToManyField, or I’m wrong?).

  • @Orion just one more thing: print([o.dealership__address for o in order.dealership.all()]) or print([o.dealership.address for o in order.dealership.all()]) was not. Did not return the address.

  • @mgibsonbr I can’t tell you, I’ve never used prefetch_related, I’ll even take a look at the documentation later

  • 1

    @Regisdasilva would not be o.address?

  • @Orion think I’m missing rsrs Thanks Again.

  • 1

    @Orion It works yes! See that code in the Pastebin: I did the same query twice, for the same set of 4 Ordered; without the prefetch_related he did 5 darlings (1 for the Ordereds and 1 for each Ordered returned by the first query - if they were 1000 results he would make 1000 darlings); with the prefetch_related he just did 2 darlings (1 for the Ordereds and 1 to find the Dealerships of all results at once - if they were 1000 results would still be a single query). Significant difference in performance! :)

Show 5 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.