获取切片后过滤Django查询集
在我维护的django论坛中,我将禁止滥用的用户,为期4天。在论坛的“主页”上,我显示每个人的评论,但不包括那些被禁止的人的评论。事情是这样的:获取切片后过滤Django查询集,django,django-models,django-queryset,Django,Django Models,Django Queryset,在我维护的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
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
以上是ListView
的get\u queryset
方法。请注意,被地狱禁制的用户无法判断他们的评论是否被排除在网站之外(地狱禁制的意义)Decired
是一个包含被禁止用户主键的列表
现在我想通过先切片,然后排除被禁止的人来优化上面的内容。我正试图通过以下方式做到这一点:
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')[:120]
queryset = queryset.exclude(submitter_id__in=condemned)
return queryset
这给了我一个错误:
获取切片后,无法筛选查询
我有什么选择?需要我能找到的最有效的解决方案,因为性能是关键。我在Django<1.8。提前谢谢 首先,Django不允许您在片段之后进行过滤,因为在底层SQL中,您无法轻松地
限制结果,然后使用where
进行过滤
不管怎样,先进行过滤,然后再进行切片可能不是问题。请注意,因此Django只能从db中获取120个对象
您需要进行一些基准测试,以确定排除是否真的在拖您的后腿。您可以测试使用exclude
和slice的查询是否明显比仅使用slice的查询慢
如果发现排除速度慢,可以使用Python进行过滤
comments = [c for c in comments if c.submitter_id not in condemned].
请注意,通过这种方式,您的评论可能会少于120条
另一个选项是向提交者
模型添加谴责
标志,然后将查询更改为.exclude(Submitter\uu ducated=True)
。这可能比当前的.exclude(submitter\u id\u in=decluded)
快
您还应该检查数据库是否有提交者id
字段的索引。因为它是一个外键,所以它可能是外键。Django的具体版本是什么?Django<1.8是不必要的模糊。查询需要多长时间?为什么你认为“先切片,然后排除被禁人员”会更快?submitter\u id
是外键吗?被谴责的
列表有多大?是的,提交者id
是一个外键,被谴责的
列表会增加到几百个对象。我会对它进行适当的基准测试,并及时与您联系,但是告诉我,如果我先切片,然后排除,我不是只会迭代120个对象吗(而在另一种情况下,我会遍历整个对象列表,排除所有被判有罪的ID,然后切片)?很酷,只需在回复中发布即可。