我有两个Django模型(简化):
class Movie(models.Model):
title = models.CharField(max_length=255)
year = models.IntegerField(max_length=4)
rating = models.DecimalField(max_digits=2, decimal_places=1, default=0)
class Request(models.Model):
movie = models.ForeignKey(Movie)
user = models.ForeignKey(User)
language = models.CharField(max_length=7, choices=settings.APP_LANGUAGES, db_index=True)
notes = models.CharField(max_length=255, blank=True, null=True)
added = models.DateTimeField(default=datetime.now)
我希望每部电影都按语言计算所有请求。我实际上提出了一个带有ORM查询的解决方案,它为我提供了我正在寻找的结果:
reqs = Request.objects.values('movie', 'langauge').annotate(Count('language'))
但是,我将需要访问其他Movie属性,而我将在模板中呈现结果。显然,上面的查询返回ValueQuerySet,如:
[{'movie': 460, 'language__count': 1, 'language': u'es-mx'}, {'movie': 458, 'language__count': 2, 'language': u'cs'}, {'movie': 459, 'language__count': 1, 'language': u'el'}]
因此reqs[0].movie.rating
之类的东西不起作用。那么,我该如何访问其他Movie属性呢?
谢谢。
答案 0 :(得分:1)
您可以这样做:
reqs = Request.objects.values('movie', 'movie__rating', 'movie__title', 'movie__year', 'language').annotate(Count('language'))
print reqs
这里是示例输出:
[
{'movie__year': 2010, 'language': u'EN', 'movie__title': u'Foo', 'movie': 1, 'language__count': 1, 'movie__rating': Decimal('1')},
{'movie__year': 2010, 'language': u'ES', 'movie__title': u'Foo', 'movie': 1, 'language__count': 1, 'movie__rating': Decimal('1')},
{'movie__year': 2010, 'language': u'RU', 'movie__title': u'Foo', 'movie': 1, 'language__count': 1, 'movie__rating': Decimal('1')},
{'movie__year': 1998, 'language': u'EN', 'movie__title': u'Bar', 'movie': 2, 'language__count': 3, 'movie__rating': Decimal('9')},
{'movie__year': 1998, 'language': u'RU', 'movie__title': u'Bar', 'movie': 2, 'language__count': 1, 'movie__rating': Decimal('9')},
]
你可以看到返回额外的电影属性不会改变计数,这里是原始查询的示例输出:
reqs = Request.objects.values('movie', 'language').annotate(Count('language'))
print reqs
这会产生输出:
[
{'movie': 1, 'language__count': 1, 'language': u'EN'},
{'movie': 1, 'language__count': 1, 'language': u'ES'},
{'movie': 1, 'language__count': 1, 'language': u'RU'},
{'movie': 2, 'language__count': 3, 'language': u'EN'},
{'movie': 2, 'language__count': 1, 'language': u'RU'},
]
修改
如果您希望能够在电影上调用方法,那么您希望在查询时选择电影,而不是请求 :
movies = Movie.objects.annotate(num_lang=Count('request__language')).all()
这将返回所有电影,按请求的语言计数进行注释,您可以通过电影上的属性* num_lang *访问这些电影。您还可以调用电影对象上的所有方法