我想计算用户对我的网站所做的贡献数量,以便我可以在网站上对他们进行排名。我设法编写了一些漂亮的代码来做到这一点,但基于每个用户。
因为用户在不同的字段中获得不同数量的积分,所以它会检查模型上的某些字段以及用户是否在其中输入了值。然后将这些值乘以它们的权重,得出总分。
没有什么比一些代码更能说明问题了:
class UserContribCounter(object):
"""Can count the number of points a user got for his contributions"""
weight_dict = {'poster':2, 'title':1}
def __init__(self, user):
if isinstance(user, User):
self.user = user
else:
raise Exception('Not a valid user instance.')
def set_contrib_points(self):
"""Some dark magic counts the number of times a certain field was filled out"""
self.unweighted = Movie.objects.filter(user = self.user).aggregate(poster=Count('poster'),title=Count('title'))
def get_contrib_points(self):
"""Multiplies the number of times a field was filled out with their weights to calculate the total number of points"""
try:
self.unweighted
except AttributeError:
self.set_contrib_points()
return sum([self.weight_dict[key] * value for key, value in self.unweighted.items()])
我还想展示前10名,所以我需要获得前10名用户。这意味着我要么必须编写一个复杂的聚合,但目前我一直没有这样做,或者我可以通过以下方式使用信号:
当模型被保存时,捕获 post_save 信号。然后使用我现有的课程为用户重新计算积分,并将其存储在用户个人资料中。这样我就可以按用户个人资料中的值对用户进行排序,这很简单。
问题是,每次保存模型时重新计数或相当复杂的聚合函数会更有效。我知道这将取决于很多事情,但我确信从概念的角度来看,应该有理由选择其中之一。请注意,我将在聚合中检查的一些字段也将是关系的,所以我不确定这将如何影响性能。
提前致谢,
叔丁基锂