Regis Santos
Regis Santos

Reputation: 3749

How to list objects in many to many Django

Considerer this 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 try

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

And generate 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.

Upvotes: 4

Views: 9606

Answers (2)

Rahul Gupta
Rahul Gupta

Reputation: 47906

It should be:

q.dealership.all() #gives a list of objects 

You can directly do this instead of using list comprehension(in the above ans).

Example: (Taken from docs)

from django.db import models

class Publication(models.Model):
    title = models.CharField(max_length=30)

    def __str__(self):              # __unicode__ on Python 2
        return self.title

    class Meta:
        ordering = ('title',)

class Article(models.Model):
    headline = models.CharField(max_length=100)
    publications = models.ManyToManyField(Publication)

    def __str__(self):              # __unicode__ on Python 2
        return self.headline

    class Meta:
        ordering = ('headline',)

Create a couple of Publications:

p1 = Publication(title='The Python Journal')
p1.save()
p2 = Publication(title='Science News')
p2.save()
p3 = Publication(title='Science Weekly')
p3.save()

Now, create an Article and the associate the Article with a Publication:

a1 = Article(headline='NASA uses Python')
a1.save()
a1.publications.add(p1, p2)
a1.publications.add(p3)

a1.publications.all()
[<Publication: Science News>, <Publication: Science Weekly>, <Publication: The Python Journal>]

Upvotes: 5

Brandon Taylor
Brandon Taylor

Reputation: 34593

You're very close:

Change:

[i.dealership for i in q.dealership.all]

to:

[dealership for dealership in q.dealership.all()]

Here's sample output from one of my model's M2M relationships on a project which demonstrates what you should see from the list comprehension. shared_with is an M2M field to a model called Profile:

>>> from polls.models import Poll
>>> polls = Poll.objects.all()
>>> for p in polls:
...   print([sw for sw in p.shared_with.all()])
... 
[<Profile: kerri>]
[<Profile: kerri>]
[]
[<Profile: jake>, <Profile: kerri>]
[<Profile: jake>, <Profile: kerri>]
[<Profile: jake>, <Profile: kerri>]
[<Profile: btaylor>]
[<Profile: jake>, <Profile: kerri>]

Upvotes: 7

Related Questions