Opened 6 years ago
Closed 6 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 , 6 years ago
| Component: | Uncategorized → Database layer (models, ORM) |
|---|---|
| Resolution: | → duplicate |
| Status: | new → closed |
| 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.