给出以下模型:
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
正常工作?