Django自定义QuerySet评估

时间:2013-11-22 21:25:05

标签: python django customization django-queryset

所以QuerySet是“懒惰的”,只在某些情况下运行(repr,list等)。我已经创建了一个用于执行许多查询的自定义QuerySet,但这些最终可能会有数百万个项目! 这比我想要的更多

返回已评估的QuerySet时,结果不应超过25个!现在我知道我可以做到以下几点:

first = example.objects.filter(...)
last = first.filter(...)
result = last[:25]
#do stuff with result

但是我会对example个对象进行很多查询,我认为没有必要使用行result = last[:25]有没有办法指定QuerySet的返回方式?

如果有,我该如何更改每当评估QuerySet 时,它只返回xQuerySet项的第一个x = 25项在这种情况下,x

重要提示:

切片必须是评估,因为这样我可以链接查询而不会产生有限的结果,但是当我在评估时返回结果时,它的最大值为{{1}}

2 个答案:

答案 0 :(得分:1)

我不确定我理解切片查询集的问题是什么。如果这是额外的代码行或困扰你的硬编码,你可以运行

example.objects.filter(**filters)[:x]

并将x传递给您正在使用的任何方法。

答案 1 :(得分:1)

您可以撰写自定义Manager

class LimitedNumberOfResultsManager(models.Manager):
    def get_queryset(self):
        return super(LimitedNumberOfResultsManager, self).get_queryset()[:25]

注意:您可能认为在此处添加切片会立即评估查询集。它不会。相反,有关查询限制的信息将保存到基础Query对象,并在最终评估期间稍后使用 - 只要在此期间不被另一个切片覆盖。

然后将经理添加到您的模型中:

class YourModel(models.Model):
    # ...

    objects = LimitedNumberOfResultsManager()

设置完YourModel.objects.all()后,您的查询集上的其他操作将始终只返回25个结果。您仍然可以使用切片随时覆盖它。例如:

这将返回最多25个结果:

YourModel.objects.filter(lorem='ipsum')

但这最多可以返回100个结果:

YourModel.objects.filter(lorem='ipsum')[:100]

还有一点。覆盖默认管理器可能会让阅读代码的其他人感到困惑。所以我认为最好不要单独使用默认管理器,而是使用自定义管理器作为可选替代方案:

class YourModel(models.Model):
    # ...

    objects = models.Manager()
    limited = LimitedNumberOfResultsManager()

通过此设置,这将返回所有结果:

YourModel.objects.all()

这将最多返回25个结果:

YourModel.limited.all()

根据您的确切用例,您还需要查看pagination in Django