您好,我创建了一个函数,该函数将根据帖子的创建时间和投票数排名来返回帖子。这是一个饲料。我不确定这是否是一种有效的方法,并且我做对很重要,因为这可能会筛选数千个帖子。我在这里简化了一些,并简要解释了每个步骤。我目前关注的问题和整个函数(没有注释)的帖子都在后面。
开始时间参数是多少小时前获得帖子。例如,如果 startHours=6,则只会返回 6 小时前创建的帖子。
def rank(request, startHours):
首先,我按投票顺序排列所有帖子
unorderedPosts=Post.objects.order_by('-votes')
然后帖子被用户指定的类别排除
if request.user.is_authenticated():
preferences=request.user.categorypreference_set.filter(on=False)
for preference in preferences:
unorderedPosts=unorderedPosts.exclude(category_name=preference.category_name)
然后我做 endHours,它总是比 startHours 参数提前 4 小时
endHours=startHours+4 #4 hour time window
现在,我对 unorderedPosts 进行切片,并仅获取从现在开始在 startHours 到 endHours 的时间窗口中创建的那些。例如,如果 startHours=4,则仅返回 4 小时前但 8 小时前创建的帖子。
posts=unorderedPosts.filter(created__gte=(timezone.now()-datetime.timedelta(hours=endHours)))
posts=posts.exclude(created__gte=(timezone.now()-datetime.timedelta(hours=startHours)))
现在我创建一个循环,将时间窗口向后移动,直到找到至少一个帖子的创建日期适合时间窗口。我设置了检查变量以防止无限循环(如果在 200 小时内未找到任何帖子,则循环将退出)。
count=posts.count()
check=endHours
while count<1 and endHours<(check+200):
endHours+=4
startHours+=4
posts=unorderedPosts.filter(created__gte=(timezone.now()-datetime.timedelta(hours=endHours)))
posts=posts.exclude(created__gte=(timezone.now()-datetime.timedelta(hours=startHours)))
count=posts.count()
if count>=1: return posts, endHours
return posts
我最关心的是在一开始就对所有帖子进行查询集。此功能旨在在小时间窗口内返回帖子,是否会通过对数据库中的所有帖子进行排名而不必要地减慢速度?我知道 django/python 查询集非常有效,但是对于包含数千个对象的集合进行排序对于这个函数来说不会很麻烦吗?
如果这是一个问题,我怎样才能在保持一切可访问的同时提高效率?
这是整个事情的帖子。
def rank(request, startHours):
unorderedPosts=Post.objects.order_by('-upVote')
if request.user.is_authenticated():
preferences=request.user.categorypreference_set.filter(on=False)
for preference in preferences: #filter by category preference
unorderedPosts=unorderedPosts.exclude(category_name=preference.category_name)
endHours=startHours+4 #4 hour time window
posts=unorderedPosts.filter(created__gte=(timezone.now()-datetime.timedelta(hours=endHours)))
posts=posts.exclude(created__gte=(timezone.now()-datetime.timedelta(hours=startHours)))
count=posts.count()
check=endHours
while count<1 and endHours<(check+200):
endHours+=4
startHours+=4
posts=unorderedPosts.filter(created__gte=(timezone.now()-datetime.timedelta(hours=endHours)))
posts=posts.exclude(created__gte=(timezone.now()-datetime.timedelta(hours=startHours)))
count=posts.count()
if count>=1: return posts
return posts