在我维护的django论坛中,我会禁止那些辱骂的用户4天。在论坛的“主页”中,我会显示每个人的评论,但不包括遭到地狱禁止的人的评论。它是这样的:
def get_queryset(self):
if self.request.user_banned: #if user is hell-banned
return Link.objects.order_by('-id')[:120]
else: #if user is not hell-banned
global condemned
queryset = Link.objects.order_by('-id').exclude(submitter_id__in=condemned)[:120]
return queryset
以上是get_queryset
的{{1}}方法。请注意,如果地狱禁止的用户不能告诉他们的评论被排除在网站之外(地狱禁令)。 ListView
是一个包含地狱禁止用户主键的列表。
现在我想首先通过切片来优化上述内容,然后将被禁止的人排除在外。我试图通过以下方式做到这一点:
condemned
这不幸地给了我错误:
切片拍摄后无法过滤查询。
我有哪些替代品?需要我能找到的最有效的解决方案,因为性能是关键。我在Django< 1.8。提前致谢。
答案 0 :(得分:0)
首先,Django不允许您在切片后进行过滤,因为在基础SQL中,您无法轻松limit
结果,然后使用where
进行过滤。
进行过滤然后切片可能不是问题。注意querysets are lazy,所以Django只会从db中获取120个对象。
您需要进行一些基准测试,以确定排除是否真的让您失望。您可以测试exclude
和切片的查询是否明显慢于仅使用切片的查询。
如果您发现排除速度很慢,可以在Python中过滤
comments = [c for c in comments if c.submitter_id not in condemned].
请注意,您最终可能会收到少于120条评论。
另一个选项是向condemned
模型添加Submitter
标记,然后将查询更改为.exclude(submitter__condemned=True)
。这可能比当前.exclude(submitter_id__in=condemned)
更快。
您还应检查您的数据库是否包含submitter_id
字段的索引。因为它是外键,所以可能会这样做。