Django:何时使用QuerySet none()

9rygscc1  于 2022-12-20  发布在  Go
关注(0)|答案(6)|浏览(189)

刚在Django的文档里看到这个
调用none()将创建一个查询集,该查询集从不返回任何对象,并且在访问结果时不会执行任何查询。qs.none()查询集是EmptyQuerySet的示例。
我构建了很多CRUD应用程序(令人惊讶),我想不出有什么情况需要使用none()
为什么要返回一个EmptyQuerySet?

vulvrdjw

vulvrdjw1#

通常是在需要提供QuerySet的情况下,但是没有可以提供的QuerySet a-比如调用一个方法或者给予一个模板。
这样做的好处是,如果您“知道”不会有结果(或者不想要结果),而您仍然“需要”一个结果,none()将不会命中数据库。
举一个不太现实的例子,假设您有一个可以查询权限的API,如果帐户还没有确认,因为您已经有了Account对象,并且可以看到account.is_activatedFalse,那么您可以跳过检查数据库权限,只使用Permission.objects.none()

ergxz8rk

ergxz8rk2#

在您想要附加到查询集但希望以空列表开始的情况下类似于我们示例化一个空列表以开始但逐渐保持向其附加有意义的值的情况示例。

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的示例(因为编程很好),而不是None[],否则以后会引起麻烦。
这样,即使没有任何条件出现True,您的代码仍然保持完整。
对于那些不了解|运算符用法的用户,请参见:

queryset |= queryset2

翻译过来就是:

queryset = queryset + queryset
blpfk2vs

blpfk2vs3#

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
nfg76nw0

nfg76nw04#

另一个很好的用例是,如果某个调用方法想要对结果调用.values_list()或类似的函数,如果该方法返回None,则会得到如下错误:
AttributeError: 'list' object has no attribute 'values_list'
但是如果您的子句返回MyModel.objects.none()而不是None,那么调用代码会很高兴,因为返回的数据是空的查询集而不是None对象。
另一种说法是,它允许您不混淆返回类型(如“此函数返回QuerySet或None”,这很混乱)。

tag5nh1u

tag5nh1u5#

在Django文档的其他例子中,查看qs.none()在哪里使用是很有用的。例如,当使用queryset初始化一个模型表单集时,如果你希望得到的表单集是空的,给出的例子是:
formset = AuthorFormSet(queryset=Author.objects.none())

5n0oy7gb

5n0oy7gb6#

none()get_queryset()中使用,根据has_view_or_change_permission()的状态返回空查询集,如下所示:

class BaseModelAdmin(metaclass=forms.MediaDefiningClass):

    # ...

    def has_view_or_change_permission(self, request, obj=None):
        return self.has_view_permission(request, obj) or self.has_change_permission(
            request, obj
        )

# ...

class InlineModelAdmin(BaseModelAdmin):

    # ...

    def get_queryset(self, request):
        queryset = super().get_queryset(request)
        if not self.has_view_or_change_permission(request):
            queryset = queryset.none() # Here
        return queryset

相关问题