[英]How to use order_by with annotate() in a custom model manager
I have these models; 我有这些模型; with one custom manager. 一位定制经理。
class OrderByHighestScoreManager(models.Manager):
def get_query_set(self, *args, **kwargs):
qs = super(OrderByHighestScoreManager, self).get_query_set(*args, **kwargs)
return qs.annotate(score=Count('votes'),).order_by('score')
class AbstractEntry(models.Model):
user = models.ForeignKey(User, null=True, blank=True)
last_modified = models.DateTimeField(auto_now=True)
objects = models.Manager()
order_by_votes = OrderByHighestScoreManager()
class Entry(AbstractEntry):
creation_date = models.DateTimeField(auto_now_add=True)
votes = generic.GenericRelation(Vote)
I can't get the custom manager to work.... This is OK: 我无法让自定义管理器开始工作。...可以:
Entry.objects.annotate(score=Count('votes__id'),).order_by('score')
This does not work: 这不起作用:
Entry.order_by_votes.all()
The error I get is: 我得到的错误是:
Traceback (most recent call last):
File "c:\Python27\Lib\unittest\case.py", line 318, in run testMethod()
File "C:\Data\Development\django_projects\oko\________\apps\entries\tests\model.py",line 111, in test_order_by_votes
self.assertEqual(list(Entry.order_by_votes.values_list('id', flat=True)), [self.e1.id, self.e2.id])
File "C:\Data\Development\django_projects\oko\lib\site-packages\django\db\models\query.py", line 84, in __len__
self._result_cache.extend(self._iter)
File "C:\Data\Development\django_projects\oko\lib\site-packages\django\db\models\query.py", line 956, in iterator
for row in self.query.get_compiler(self.db).results_iter():
File "C:\Data\Development\django_projects\oko\lib\site-packages \django\db\models\sql\compiler.py", line 680, in results_iter
for rows in self.execute_sql(MULTI):
File "C:\Data\Development\django_projects\oko\lib\site-packages\django\db\models\sql\compiler.py", line 725, in execute_sql
sql, params = self.as_sql()
File "C:\Data\Development\django_projects\oko\lib\site-packages\django\db\models\sql\compiler.py", line 60, in as_sql
ordering, ordering_group_by = self.get_ordering()
File "C:\Data\Development\django_projects\oko\lib\site-packages\django\db\models\sql\compiler.py", line 349, in get_ordering
self.query.model._meta, default_order=asc):
File "C:\Data\Development\django_projects\oko\lib\site-packages\django\db\models\sql\compiler.py", line 378, in find_ordering_name
opts, alias, False)
File "C:\Data\Development\django_projects\oko\lib\site-packages \django\db\models\sql\query.py", line 1238, in setup_joins
"Choices are: %s" % (name, ", ".join(names)))
FieldError: Cannot resolve keyword 'score' into field. Choices are:
creation_date, id, last_modified, user, votes
What's going wrong here? 这是怎么了
I would very much like to perform this sorting via a manager, or at least a method accessible from within an Entry instance as several templates will be using this special sorting (and I don't want to copy this complex queryset over different views). 我非常想通过管理器或至少从Entry实例可访问的方法来执行这种排序,因为几个模板将使用这种特殊排序(并且我不想在不同的视图上复制此复杂的查询集)。
Thanks, your response was helpful in figuring out my own, slightly different approach. 谢谢,您的回答有助于我们找出我自己略有不同的方法。
class AbstractEntryManager(models.Manager):
def by_score(self):
qs = super(OrderByHighestScoreManager, self).get_query_set()
return qs.annotate(score=Count('votes')).order_by('score')
class AbstractEntry(models.Model):
...
objects = AbstractEntryManager()
then in your View use: Entry.objects.by_score()
然后在您的视图中使用: Entry.objects.by_score()
This make sense if you'll only even need the annotation for ordering (which is the case for my use). 如果您甚至只需要注释就可以订购(我便是这种情况),这是有道理的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.