获取切片后过滤Django查询集

获取切片后过滤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

在我维护的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
以上是
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,然后切片)?很酷,只需在回复中发布即可。