Opened 4 years ago

Closed 4 years ago

#31137 closed Bug (duplicate)

TypeError when ordering by a ForeignKey field to a model which orders by Length().

Reported by: Jeremy Stretch Owned by: nobody
Component: Database layer (models, ORM) Version: 2.2
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I have two models, Foo and Bar, both of which are ordered "naturally" by the length of their name field and its value. Bar has a ForeignKey to Foo, which it also uses for ordering.

from django.db import models
from django.db.models.functions import Length


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

    class Meta:
        ordering = (Length('name').asc(), 'name')


class Bar(models.Model):
    foo = models.ForeignKey(to='Foo', on_delete=models.CASCADE)
    name = models.CharField(max_length=50)

    class Meta:
        ordering = ('foo', Length('name').asc(), 'name')

I am able to generate migrations for this arrangement successfully, however when calling Bar.objects.all(), I get a TypeError:

>>> from utilities.models import Bar, Foo
>>> Bar.objects.all()
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/home/jstretch/.virtualenvs/netbox/lib/python3.6/site-packages/django/db/models/query.py", line 250, in __repr__
    data = list(self[:REPR_OUTPUT_SIZE + 1])
  File "/home/jstretch/.virtualenvs/netbox/lib/python3.6/site-packages/django/db/models/query.py", line 274, in __iter__
    self._fetch_all()
  File "/home/jstretch/.virtualenvs/netbox/lib/python3.6/site-packages/cacheops/query.py", line 277, in _fetch_all
    return self._no_monkey._fetch_all(self)
  File "/home/jstretch/.virtualenvs/netbox/lib/python3.6/site-packages/django/db/models/query.py", line 1242, in _fetch_all
    self._result_cache = list(self._iterable_class(self))
  File "/home/jstretch/.virtualenvs/netbox/lib/python3.6/site-packages/django/db/models/query.py", line 55, in __iter__
    results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
  File "/home/jstretch/.virtualenvs/netbox/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 1120, in execute_sql
    sql, params = self.as_sql()
  File "/home/jstretch/.virtualenvs/netbox/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 474, in as_sql
    extra_select, order_by, group_by = self.pre_sql_setup()
  File "/home/jstretch/.virtualenvs/netbox/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 55, in pre_sql_setup
    order_by = self.get_order_by()
  File "/home/jstretch/.virtualenvs/netbox/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 330, in get_order_by
    field, self.query.get_meta(), default_order=asc))
  File "/home/jstretch/.virtualenvs/netbox/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 720, in find_ordering_name
    order, already_seen))
  File "/home/jstretch/.virtualenvs/netbox/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 701, in find_ordering_name
    name, order = get_order_dir(name, default_order)
  File "/home/jstretch/.virtualenvs/netbox/lib/python3.6/site-packages/django/db/models/sql/query.py", line 2154, in get_order_dir
    if field[0] == '-':
TypeError: 'OrderBy' object does not support indexing

It seems that get_order_dir() expects to always receive a string and does not support the use of a function. As far as I can tell from the documentation, this approach should be supported, but I apologize if I've missed something.

Change History (1)

comment:1 by Mariusz Felisiak, 4 years ago

Component: UncategorizedDatabase layer (models, ORM)
Resolution: duplicate
Status: newclosed
Summary: TypeError when ordering by a ForeignKey field to a model which orders by Length()TypeError when ordering by a ForeignKey field to a model which orders by Length().

Duplicate of #30557.

This issue was fixed in 8c5f9906c56ac72fc4f13218dd90bdf9bc8a248b (Django 3.0). Unfortunately this patch doesn't qualify for a backport to the Django 2.2.

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