Opened 10 years ago

Closed 10 years ago

#7780 closed (invalid)

get returns multiple objects when model includes a ManyToManyField in the default ordering

Reported by: max@… Owned by: nobody
Component: Uncategorized Version: master
Severity: Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:


Django throws a MultipleObjectsReturned error when getting a single instance of a model that includes a ManyToManyField in the default ordering.

It seems that the related table is joined with an inner join and so the resulting query has extra rows.
I traced the join to the function get_ordering of django\db\models\sql\

This simple example illustrates the issue best:

from django.db import models

class Topping(models.Model):
    name  = models.CharField(max_length = 50)

    def __unicode__(self):

class Pizza(models.Model):
    name = models.CharField(max_length = 50)
    toppings = models.ManyToManyField(Topping)

    def __unicode__(self):

    class Meta:

# test with the following 
# create some toppings
tomato = Topping(name="Tomato")
mozzarella = Topping(name="Mozzarella")

# create a pizza
pizza = Pizza(name="Margareta")

# add the toppings

# select the pizza
p = Pizza.objects.get(pk=1)

# You should get the following error:
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "c:\python25\lib\site-packages\django\db\models\", line 82, in get return self.get_query_set().get(*args, **kwargs)
  File "c:\python25\lib\site-packages\django\db\models\", line 285, in get % (self.model._meta.object_name, num, kwargs))
MultipleObjectsReturned: get() returned more than one Pizza -- it returned 2! Lookup parameters were {'pk': 1}

Attachments (1) (1.2 KB) - added by max@… 10 years ago.
Example models and test code

Download all attachments as: .zip

Change History (2)

Changed 10 years ago by max@…

Attachment: added

Example models and test code

comment:1 Changed 10 years ago by Malcolm Tredinnick

Resolution: invalid
Status: newclosed

"Doctor it hurts when I do this".. "Then don't do that, sir".

As noted in the documentation for ordering, it is legal to include multi-valued fields because there are some situations where it returns sensible results, so prohibiting them always leads to undesired restrictions. That does not mean that including them is a sensible thing to do and you should always never do it.

This isn't a bug in Django because the functionality is needed in some cases. The solution is not to include that field in your default ordering (ordering by multiple valued results hardly ever makes sense).

Note: See TracTickets for help on using tickets.
Back to Top