#26092: Regression when using order_by() on a ManyToManyField using the
'through'
feature
-------------------------------------+-------------------------------------
Reporter: wjakob | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: 1.9
(models, ORM) |
Severity: Release blocker | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by timgraham):
* stage: Unreviewed => Accepted
* severity: Normal => Release blocker
Old description:
> Hi,
>
> I'm seeing a serious regression (AttributeError exception thrown) when
> using the order_by() feature on a ManyToManyField in combination with the
> 'through' feature.
>
> This worked perfectly fine in Django 1.8.x, I'm seeing it for the first
> time now. IMHO it is a release blocker, but then the release is already
> out (so I set the severity as 'Normal').
>
> See below for a minimal example:
>
> {{{#!python
> from django.db import models
>
> class Person(models.Model):
> name = models.CharField(max_length=200)
>
> class Publication(models.Model):
> title = models.CharField(max_length=200)
> authors = models.ManyToManyField(Person, through='Author')
>
> def get_authors(self):
> return self.authors.order_by('author_to_publication')
>
> class Author(models.Model):
> person = models.ForeignKey(Person, verbose_name='Author',
> related_name='author_to_publication')
> publication = models.ForeignKey(Publication,
> verbose_name='Publication')
> order_id = models.PositiveSmallIntegerField(default=0)
>
> class Meta:
> ordering = ['order_id']
> }}}
>
> And here is an example shell session which causes the problem
>
> {{{#!python
> % ./manage.py shell
> [INS]
> Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 23 2015, 02:52:03)
> [GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
> Type "help", "copyright", "credits" or "license" for more information.
> (InteractiveConsole)
> >>>
> >>> person = myapp.models.Person()
> >>> person.save()
> >>>
> >>> publication = myapp.models.Publication(title='test publication')
> >>> publication.save()
> >>> author = myapp.models.Author(person=person, publication=publication,
> order_id=1)
> >>> author.save()
> >>>
> >>> publication.authors.order_by('author_to_publication')
> Traceback (most recent call last):
> File "<console>", line 1, in <module>
> File "/Users/wenzel/mysite/lib/python3.4/site-
> packages/django/db/models/query.py", line 234, in __repr__
> data = list(self[:REPR_OUTPUT_SIZE + 1])
> File "/Users/wenzel/mysite/lib/python3.4/site-
> packages/django/db/models/query.py", line 258, in __iter__
> self._fetch_all()
> File "/Users/wenzel/mysite/lib/python3.4/site-
> packages/django/db/models/query.py", line 1074, in _fetch_all
> self._result_cache = list(self.iterator())
> File "/Users/wenzel/mysite/lib/python3.4/site-
> packages/django/db/models/query.py", line 52, in __iter__
> results = compiler.execute_sql()
> File "/Users/wenzel/mysite/lib/python3.4/site-
> packages/django/db/models/sql/compiler.py", line 837, in execute_sql
> sql, params = self.as_sql()
> File "/Users/wenzel/mysite/lib/python3.4/site-
> packages/django/db/models/sql/compiler.py", line 382, in as_sql
> extra_select, order_by, group_by = self.pre_sql_setup()
> File "/Users/wenzel/mysite/lib/python3.4/site-
> packages/django/db/models/sql/compiler.py", line 49, in pre_sql_setup
> order_by = self.get_order_by()
> File "/Users/wenzel/mysite/lib/python3.4/site-
> packages/django/db/models/sql/compiler.py", line 295, in get_order_by
> field, self.query.get_meta(), default_order=asc))
> File "/Users/wenzel/mysite/lib/python3.4/site-
> packages/django/db/models/sql/compiler.py", line 571, in
> find_ordering_name
> if field.is_relation and path and opts.ordering and name !=
> field.attname:
> AttributeError: 'ManyToOneRel' object has no attribute 'attname'
> >>>
> }}}
New description:
Hi,
I'm seeing a serious regression (AttributeError exception thrown) when
using the order_by() feature on a ManyToManyField in combination with the
'through' feature.
This worked perfectly fine in Django 1.8.x, I'm seeing it for the first
time now. IMHO it is a release blocker, but then the release is already
out (so I set the severity as 'Normal').
See below for a minimal example:
{{{#!python
class Person(models.Model):
name = models.CharField(max_length=200)
class Publication(models.Model):
title = models.CharField(max_length=200)
authors = models.ManyToManyField(Person, through='Author')
class Author(models.Model):
person = models.ForeignKey(Person,
related_name='author_to_publication')
publication = models.ForeignKey(Publication)
order_id = models.PositiveSmallIntegerField(default=0)
class Meta:
ordering = ['order_id']
}}}
And here is an example test which causes the problem:
{{{#!python
from django.test import TestCase
from .models import Person, Publication, Author
class Test(TestCase):
def test(self):
person = Person()
person.save()
publication = Publication(title='test publication')
publication.save()
author = Author(person=person, publication=publication,
order_id=1)
author.save()
list(publication.authors.order_by('author_to_publication'))
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/Users/wenzel/mysite/lib/python3.4/site-
packages/django/db/models/query.py", line 234, in __repr__
data = list(self[:REPR_OUTPUT_SIZE + 1])
File "/Users/wenzel/mysite/lib/python3.4/site-
packages/django/db/models/query.py", line 258, in __iter__
self._fetch_all()
File "/Users/wenzel/mysite/lib/python3.4/site-
packages/django/db/models/query.py", line 1074, in _fetch_all
self._result_cache = list(self.iterator())
File "/Users/wenzel/mysite/lib/python3.4/site-
packages/django/db/models/query.py", line 52, in __iter__
results = compiler.execute_sql()
File "/Users/wenzel/mysite/lib/python3.4/site-
packages/django/db/models/sql/compiler.py", line 837, in execute_sql
sql, params = self.as_sql()
File "/Users/wenzel/mysite/lib/python3.4/site-
packages/django/db/models/sql/compiler.py", line 382, in as_sql
extra_select, order_by, group_by = self.pre_sql_setup()
File "/Users/wenzel/mysite/lib/python3.4/site-
packages/django/db/models/sql/compiler.py", line 49, in pre_sql_setup
order_by = self.get_order_by()
File "/Users/wenzel/mysite/lib/python3.4/site-
packages/django/db/models/sql/compiler.py", line 295, in get_order_by
field, self.query.get_meta(), default_order=asc))
File "/Users/wenzel/mysite/lib/python3.4/site-
packages/django/db/models/sql/compiler.py", line 571, in
find_ordering_name
if field.is_relation and path and opts.ordering and name !=
field.attname:
AttributeError: 'ManyToOneRel' object has no attribute 'attname'
}}}
--
Comment:
Bisected to d43aa28f67c52bc6f5ea5868c711df263895713f
--
Ticket URL: <https://code.djangoproject.com/ticket/26092#comment:3>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/064.1c7c5dc13584e5eee570e801d079786e%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.