Opened 2 years ago

Closed 2 years ago

#29272 closed Bug (duplicate)

Queryset using order_by(F()) fails to compile with values_list

Reported by: bszfw Owned by: nobody
Component: Database layer (models, ORM) Version: 2.0
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

Here is a simplified version of what I am trying to do:

from django.db import models
from django.db.models import IntegerField, F, Value

class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')

    def __str__(self):
        return self.question_text

Question.objects.annotate(test=Value(1, output_field=IntegerField())).order_by(F('test')).values_list('question_text')

It works without using F, or by adding the annotated value to values_list.
But I need F to be able to write F('test').asc(nulls_last=True), and I cannot modify values_list as it is added to the Queryset later in code which does not know anything about the annotation.

Change History (2)

comment:1 Changed 2 years ago by Simon Charette

Could you possibly provide the exact traceback you encounter?

Also you should be able to pass your expression directly to order_by

Question.objects.order_by(
    Value(1, output_field=IntegerField()).asc(nulls_last=True),
).values_list('question_text')

comment:2 Changed 2 years ago by Tim Graham

Resolution: duplicate
Status: newclosed

The traceback:

Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "django/db/models/query.py", line 248, in __repr__
    data = list(self[:REPR_OUTPUT_SIZE + 1])
  File "django/db/models/query.py", line 272, in __iter__
    self._fetch_all()
  File "django/db/models/query.py", line 1179, in _fetch_all
    self._result_cache = list(self._iterable_class(self))
  File "django/db/models/query.py", line 138, in __iter__
    return compiler.results_iter(tuple_expected=True, chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
  File "django/db/models/sql/compiler.py", line 1018, in results_iter
    results = self.execute_sql(MULTI, chunked_fetch=chunked_fetch, chunk_size=chunk_size)
  File "django/db/models/sql/compiler.py", line 1054, in execute_sql
    sql, params = self.as_sql()
  File "django/db/models/sql/compiler.py", line 447, in as_sql
    extra_select, order_by, group_by = self.pre_sql_setup()
  File "django/db/models/sql/compiler.py", line 51, in pre_sql_setup
    order_by = self.get_order_by()
  File "django/db/models/sql/compiler.py", line 346, in get_order_by
    self.query, allow_joins=True, reuse=None)
  File "django/db/models/expressions.py", line 248, in resolve_expression
    for expr in c.get_source_expressions()
  File "django/db/models/expressions.py", line 248, in <listcomp>
    for expr in c.get_source_expressions()
  File "django/db/models/expressions.py", line 516, in resolve_expression
    return query.resolve_ref(self.name, allow_joins, reuse, summarize)
  File "django/db/models/sql/query.py", line 1518, in resolve_ref
    return self.annotation_select[name]
KeyError: 'test'

Duplicate of #28811 which will be fixed in Django 2.1.

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