Django - 按日期和平均值查询聚合
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django - 按日期和平均值查询聚合相关的知识,希望对你有一定的参考价值。
我有一个应用程序,其中Gym
与许多Surveys
(多对多)相关联,而Survey
有许多Answers
。
Answer
有一个数字value
,它与Survey
和Gym
有关。
models.朋友
class DateTimeModel(models.Model):
creation_date = models.DateTimeField(verbose_name=_('Creation Date'), auto_now_add=True, db_index=True)
edit_date = models.DateTimeField(verbose_name=_('Last Edit Date'), auto_now=True, db_index=True)
...
class Gym(DateTimeModel):
name = models.CharField(max_length=250)
...
class Survey(DateTimeModel):
text = models.CharField(max_length=500)
valid_from = models.DateTimeField()
valid_to = models.DateTimeField()
gyms = models.ManyToManyField(Gym)
...
class Answer(DateTimeModel):
value = models.IntegerField()
survey = models.ForeignKey(Survey, on_delete=models.CASCADE)
gym = models.ForeignKey(Gym, on_delete=models.PROTECT)
...
我需要在一天之内获得特定健身房的投票分配。这很容易实现:
views.朋友
class VotesDistributionByDayViewSet(APIView):
@staticmethod
def get(request, gym_id, survey_id):
votes_by_date = Answer.objects.filter(gym_id=gym_id, survey_id=survey_id)
.annotate(day=TruncDay('creation_date'))
.values("day")
.annotate(count=Count('gym_id'))
.order_by('day')
return Response({
'votes_by_gym': votes_by_date,
})
这将返回以下响应(这是正确的):
{
"votes_by_gym": [
{
"day": "2018-06-11T00:00:00+02:00",
"count": 15
},
{
"day": "2018-06-12T00:00:00+02:00",
"count": 6
},
{
"day": "2018-06-13T00:00:00+02:00",
"count": 17
},
{
"day": "2018-06-14T00:00:00+02:00",
"count": 12
},
...
现在我需要按天返回所有健身房的平均答案数。我尝试了以下查询:
avg_votes_by_date = Answer.objects
.exclude(gym_id=8)
.filter(survey_id=survey_id)
.annotate(day=TruncDay('creation_date'))
.values("day")
.annotate(count_answers=Count('gym_id'))
.annotate(count_gym=Count('gym_id', distinct=True))
.order_by('day')
返回以下响应:
"avg_votes_by_date": [
{
"day": "2018-06-11T00:00:00+02:00",
"count_answers": 15,
"count_gym": 1
},
{
"day": "2018-06-12T00:00:00+02:00",
"count_answers": 6,
"count_gym": 1
},
{
"day": "2018-06-13T00:00:00+02:00",
"count_answers": 17,
"count_gym": 1
},
{
"day": "2018-06-14T00:00:00+02:00",
"count_answers": 12,
"count_gym": 2
},
{
"day": "2018-06-15T00:00:00+02:00",
"count_answers": 29,
"count_gym": 2
},
如何使用count_answers / count_gym
的结果添加第三个键?有没有更好的方法来获得这个平均值?
答案
对于第二个查询,我建议您在所选值中注释“count_answers”和“count_gym”,然后除以转换:
avg_votes_by_date = Answer.objects
.exclude(gym_id=8)
.filter(survey_id=survey_id)
.annotate(day=TruncDay('creation_date'))
.values('day')
.annotate(count_answers=Count('gym_id'))
.annotate(count_gym=Count('gym_id', distinct=True))
.annotate(avg=Cast(F('count_answers'), FloatField()) / Cast(F('count_gym'), FloatField()))
.order_by('day')
以上是关于Django - 按日期和平均值查询聚合的主要内容,如果未能解决你的问题,请参考以下文章