鉴于这两个模型:
class Profile(models.Model):
user = models.ForeignKey(User, unique=True, verbose_name=_('user'))
about = models.TextField(_('about'), blank=True)
zip = models.CharField(max_length=10, verbose_name='zip code', blank=True)
website = models.URLField(_('website'), blank=True, verify_exists=False)
class ProfileView(models.Model):
profile = models.ForeignKey(Profile)
viewer = models.ForeignKey(User, blank=True, null=True)
created = models.DateTimeField(auto_now_add=True)
我想让所有个人资料按总观看次数排序。我可以获得一个按总视图排序的配置文件ID列表:
ProfileView.objects.values('profile').annotate(Count('profile')).order_by('-profile__count')
但这只是一个配置文件ID的字典,这意味着我必须循环它并将一个配置文件对象列表放在一起。这是一些额外的查询,仍然不会导致QuerySet。那时,我不妨放弃原始SQL。在我这样做之前,有没有办法从Profile模型中做到这一点? ProfileViews通过ForeignKey字段相关,但它不像Profile模型那样知道,所以我不确定如何将两者结合在一起。
顺便说一句,我意识到我可以将视图作为属性存储在Profile模型上,这可能就是我在这里所做的,但我仍然有兴趣学习如何更好地使用聚合函数。 / p>
答案 0 :(得分:10)
ProfileViews通过ForeignKey字段相关,但它不像Profile模型那样知道
Profile模型确实知道这一点。 您应该可以执行以下操作:
Profile.objects.all().annotate(count_views=Count('profileview__pk')).order_by('count_views')
修改:在这里,您可以找到有关跨越关系http://docs.djangoproject.com/en/dev/topics/db/queries/#lookups-that-span-relationships
的查找的Django文档答案 1 :(得分:4)
肯定会有效:
Profile.objects.all().annotate(viewcount=Count('profileview')).order_by('-viewcount')
正如Botondus所说,Profile模型知道向后的ForeignKey关系。