Python 基于多重关系的模型优化设计
我正在尝试创建一个联盟排行榜,我正在尝试确定一个最佳结构,以避免出现问题 目前,我有三个模型代表我希望收集的数据。季节、挑战、尝试 现在,我假设下面的陈述是正确的,我希望从中得到 一个季节持续一年 挑战赛持续一个月 一个赛季可能会有很多挑战 挑战可以有很多尝试 一项挑战不能属于多个赛季 一次尝试不能属于多个挑战。 当我尝试显示数据时,我会感到困难。我想返回当前赛季的排行榜,它计算用户在每个挑战中的最佳尝试,并返回一个查询集,其中包含用户及其整个赛季的总分 示例数据 预期结果 挑战者2-20分 挑战者1-10分 如何使此模型更好地表示我需要的结果。我已经看过一段完整的关系,但我不确定我是否完全理解它,或者在这里是否需要它Python 基于多重关系的模型优化设计,python,django,django-models,Python,Django,Django Models,我正在尝试创建一个联盟排行榜,我正在尝试确定一个最佳结构,以避免出现问题 目前,我有三个模型代表我希望收集的数据。季节、挑战、尝试 现在,我假设下面的陈述是正确的,我希望从中得到 一个季节持续一年 挑战赛持续一个月 一个赛季可能会有很多挑战 挑战可以有很多尝试 一项挑战不能属于多个赛季 一次尝试不能属于多个挑战。 当我尝试显示数据时,我会感到困难。我想返回当前赛季的排行榜,它计算用户在每个挑战中的最佳尝试,并返回一个查询集,其中包含用户及其整个赛季的总分 示例数据 预期结果 挑战者2-20分 挑
还有,我如何使用ORM获得我想要的结果呢?你的模型很好,不要改变它。要获得想要的结果,请尝试以下方法:
Attempt.objects.filter(challenge__season__season='2019').values('challenger__name').annotate(total_points=Sum('points')).order_by('-total_points')
这需要所有的尝试,将它们过滤到名称为“2019”的季节,然后获取所有挑战者的名称,然后通过挑战者的尝试点数总和进行聚合,这似乎是您想要的,但您也可以使用Max而不是sum
这种方法的一个问题,顺便说一句,我必须归功于这个来源:如果多个挑战者有相同的名字,他们将被分组在一起,这可能是你不想要的。因此,您可能希望以挑战者“pk”和“name”来分组。3、4、5、6已准备就绪。1和2只是用数据填充。我知道这些模型反映了我的假设,我的问题是,尽管当前的设计反映了这一点,但我觉得它不适合让我获得我想要的结果。我只是不明白什么是Challenger 2-20点?这是我希望根据上述对象中的数据返回的结果。将生成良好的模式,正是你想要的IMHO。如果你想要完整的模型对象而不仅仅是值,你可以通过“challenger\u pk”来使用.group\u,而不是使用.values。。。
Season(season='2019',
start_date=..., # some date object
end_date=..., # some date object
)
Challenge(season=1, # represents season object above
name='Challenge 1',
start_date=..., # some date object
end_date=..., # some date object
)
Challenge(season=1, # represents season object above
name='Challenge 2',
start_date=..., # some date object
end_date=... # some date object
)
Attempt(challenger=1, # represents user object
challenge=1, # represents challenge 1 above
points=5
)
Attempt(challenger=2, # represents user object
challenge=1, # represents challenge 1 above
points=10
)
Attempt(challenger=1, # represents user object
challenge=2, # represents challenge 2 above
points=5
)
Attempt(challenger=2, # represents user object
challenge=2, # represents challenge 2 above
points=10
)
Attempt.objects.filter(challenge__season__season='2019').values('challenger__name').annotate(total_points=Sum('points')).order_by('-total_points')