Python Django自定义查询集评估

Python Django自定义查询集评估,python,django,customization,django-queryset,Python,Django,Customization,Django Queryset,因此QuerySets是“惰性的”,只在某些实例(repr、list等)中运行。我已经创建了一个自定义的QuerySet,用于执行许多查询,但这些查询最终可能会有数百万项这比我想返回的要多得多 返回已评估的查询集时,其结果不应超过25个!现在我知道我可以做到以下几点: first = example.objects.filter(...) last = first.filter(...) result = last[:25] #do stuff with result 但是,我将使用示例对象进

因此
QuerySet
s是“惰性的”,只在某些实例(repr、list等)中运行。我已经创建了一个自定义的
QuerySet
,用于执行许多查询,但这些查询最终可能会有数百万项这比我想返回的要多得多

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

first = example.objects.filter(...)
last = first.filter(...)
result = last[:25]
#do stuff with result
但是,我将使用
示例
对象进行大量查询,因此我觉得没有必要使用
result=last[:25]
是否有方法指定如何返回
QuerySet

如果有,我如何更改它,使每当
查询集
被评估时
它只返回
查询集
中的第一个
x
项,在这种情况下,
x=25

重要提示:
切片必须在求值时进行,因为这样我可以在没有有限结果的情况下链接查询,但是当我在求值时返回结果时,它的最大值将为
x

我不确定我是否理解您在切片查询集时遇到的问题。如果是额外的代码行或硬编码的数字困扰着你,你可以运行

example.objects.filter(**filters)[:x]
并将x传递到您正在使用的任何方法中。

您可以编写一个自定义:

注意:您可能认为在这里添加一个切片将立即计算queryset。不会的。相反,有关查询限制的信息将保存到基础
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()


根据您的具体用例,您也需要查看。

这是额外的一行代码,我知道我可以使用
x
,我只是觉得它没有必要,因为它会被调用很多次,就像数千次一样,而且我不能为每个自定义过滤器执行此操作,因为切片会对其进行评估,然后您就不能说:“通常,切片一个查询集会返回一个新的查询集——它不会对查询求值。”所以我认为你的答案是正确的。@möter”一般来说“在某些情况下,时间是极其重要的,我不能冒险去评估它。这也是一个API,它将打破API@m此外,我还必须在每个查询方法的末尾添加一个片段,其中有50个以上的查询方法,许多查询方法将继续添加。如果我能让它总是返回第一个
x
结果,那就太理想了。@RyanSaxe在这里通常是指不使用'step'参数进行切片时。
YourModel.limited.all()