如何按嵌套注释字段排序?

时间:2018-08-06 06:16:11

标签: python django

给出以下模型:

from django.db import models


class FooQuerySet(models.QuerySet):
    def with_baz(self):
        return self.annotate(baz=models.F('pk'))


class Foo(models.Model):
    objects = FooQuerySet.as_manager()


class Bar(models.Model):
    foo = models.ForeignKey(Foo, on_delete=models.CASCADE)

以及以下设置:

In[2]: from main.models import *
In[3]: f = Foo.objects.create()
In[4]: b = Bar.objects.create(foo=f)

如何构建通过Bar字段对Foo.baz个对象进行排序的查询?

尝试了以下内容:

In[5]: from django.db.models import Prefetch
In[6]: Bar.objects.prefetch_related(Prefetch('foo', queryset=Foo.objects.with_baz())).order_by('foo__baz')

错误:

Traceback (most recent call last):
  File "/Users/soon/anaconda3/envs/django-main/lib/python3.6/site-packages/IPython/core/formatters.py", line 224, in catch_format_error
    r = method(self, *args, **kwargs)
  File "/Users/soon/anaconda3/envs/django-main/lib/python3.6/site-packages/IPython/core/formatters.py", line 702, in __call__
    printer.pretty(obj)
  File "/Users/soon/anaconda3/envs/django-main/lib/python3.6/site-packages/IPython/lib/pretty.py", line 400, in pretty
    return _repr_pprint(obj, self, cycle)
  File "/Users/soon/anaconda3/envs/django-main/lib/python3.6/site-packages/IPython/lib/pretty.py", line 695, in _repr_pprint
    output = repr(obj)
  File "/Users/soon/anaconda3/envs/django-main/lib/python3.6/site-packages/django/db/models/query.py", line 248, in __repr__
    data = list(self[:REPR_OUTPUT_SIZE + 1])
  File "/Users/soon/anaconda3/envs/django-main/lib/python3.6/site-packages/django/db/models/query.py", line 272, in __iter__
    self._fetch_all()
  File "/Users/soon/anaconda3/envs/django-main/lib/python3.6/site-packages/django/db/models/query.py", line 1179, in _fetch_all
    self._result_cache = list(self._iterable_class(self))
  File "/Users/soon/anaconda3/envs/django-main/lib/python3.6/site-packages/django/db/models/query.py", line 53, in __iter__
    results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
  File "/Users/soon/anaconda3/envs/django-main/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 1053, in execute_sql
    sql, params = self.as_sql()
  File "/Users/soon/anaconda3/envs/django-main/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 446, in as_sql
    extra_select, order_by, group_by = self.pre_sql_setup()
  File "/Users/soon/anaconda3/envs/django-main/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 51, in pre_sql_setup
    order_by = self.get_order_by()
  File "/Users/soon/anaconda3/envs/django-main/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 316, in get_order_by
    field, self.query.get_meta(), default_order=asc))
  File "/Users/soon/anaconda3/envs/django-main/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 663, in find_ordering_name
    field, targets, alias, joins, path, opts = self._setup_joins(pieces, opts, alias)
  File "/Users/soon/anaconda3/envs/django-main/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 696, in _setup_joins
    pieces, opts, alias)
  File "/Users/soon/anaconda3/envs/django-main/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1448, in setup_joins
    names, opts, allow_many, fail_on_missing=True)
  File "/Users/soon/anaconda3/envs/django-main/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1379, in names_to_path
    "Choices are: %s" % (name, ", ".join(available)))
django.core.exceptions.FieldError: Cannot resolve keyword 'baz' into field. Choices are: bar, id

但是它返回带有带注释字段的Foo对象(因此prefetch_related + annotate可以工作):

In[7]: Bar.objects.prefetch_related(Prefetch('foo', queryset=Foo.objects.with_baz())).first().foo.baz
Out[7]: 1

当我注释顶级模型时,order_by可以正常工作:

In[9]: Bar.objects.annotate(baz=models.F('foo__pk')).order_by('baz')
Out[9]: <QuerySet [<Bar: Bar object (1)>]>

但是我如何使prefetch_related + annotate + order_by正常工作?

0 个答案:

没有答案