Opened 5 years ago

Last modified 5 years ago

#26092 closed Bug

Regression when using order_by() on a ManyToManyField using the 'through' feature — at Initial Version

Reported by: Wenzel Jakob Owned by: nobody
Component: Database layer (models, ORM) Version: 1.9
Severity: Release blocker Keywords:
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

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:

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

 % ./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'
>>>

Change History (0)

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