38

刚刚在django 文档中遇到了这个

调用 none() 将创建一个从不返回任何对象的查询集,并且在访问结果时不会执行任何查询。qs.none() 查询集是 EmptyQuerySet 的一个实例。

我构建了很多 CRUD 应用程序(惊喜),但我想不出我需要使用none().

为什么要返回一个 EmptyQuerySet?

4

5 回答 5

39

通常在您需要提供QuerySet,但没有提供的情况下 - 例如调用方法或提供给模板。

优点是如果您知道不会有结果(或不想要结果)并且您仍然需要一个结果,none()则不会访问数据库。

举一个不切实际的例子,假设您有一个 API,您可以在其中查询您的权限。如果帐户尚未确认,因为您已经拥有该Account对象并且您可以看到它account.is_activatedFalse您可以跳过检查数据库的权限,只需使用Permission.objects.none()

于 2013-01-12T03:30:17.600 回答
17

如果您想附加到查询集但希望以空列表开头类似于我们实例化一个空列表以开始但逐渐向其附加有意义的值的情况示例..

def get_me_queryset(conditionA, conditionB, conditionC):
    queryset = Model.objects.none()

    if conditionA:
        queryset |= some_complex_computation(conditionA)
    elif conditionB:
        queryset |= some_complex_computation(conditionB)

    if conditionC:
        queryset |= some_simple_computation(conditionC)

    return queryset

get_me_queryset应该几乎总是返回实例django.db.models.query.QuerySet(因为良好的编程)而不是Noneor [],否则它会在以后引入头痛..

这样即使没有条件出现True,您的代码仍将保持不变。不再进行类型检查

对于那些不了解|操作员在这里的用法的人:

queryset |= queryset2

它转化为:

queryset = queryset + queryset
于 2015-09-04T10:23:53.480 回答
2

queryset.none 的另一个用途是当您不知道是否会有对象但不想引发错误时。

例子:

class DummyMixin(object):

    def get_context_data(self,**kwargs):
        """ Return all the pks of objects into the context """

        context = super(DummyMixin, self).get_context_data(**kwargs)

        objects_pks = context.get(
            "object_list",
            Mymodel.objects.none()
        ).values_list("pk", flat=True)

        context["objects_pks"] = objects_pks
于 2015-12-02T13:04:20.107 回答
2

另一个很好的用例是如果某些调用方法想要调用.values_list()或类似结果。如果该方法返回 None,您将收到类似的错误

AttributeError: 'list' object has no attribute 'values_list'

但是如果你的子句返回MyModel.objects.none()而不是None,调用代码会很高兴,因为返回的数据是一个空的查询集而不是一个 None 对象。

Another way of putting it is that it allows you to not mix up return types (like "this function returns a QuerySet or None," which is messy).

于 2019-05-10T19:06:57.113 回答
1

查看qs.none()Django 文档中其他示例中使用的位置很有用。例如,在使用查询集初始化模型表单集时,如果您希望结果表单集为空,则给出的示例是:

formset = AuthorFormSet(queryset=Author.objects.none())

于 2018-10-26T15:17:37.067 回答