【问题标题】:Django: When To Use QuerySet NoneDjango:何时使用 QuerySet 无
【发布时间】:2012-12-26 17:27:12
【问题描述】:

刚刚在django docs看到这个

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

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

为什么要返回一个 EmptyQuerySet?

【问题讨论】:

    标签: python django


    【解决方案1】:

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

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

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

    【讨论】:

    • 我相信这是正确的,但我会指出,一些核心开发人员似乎支持删除 None() 方法。请参阅票 django 支持票 19184 code.djangoproject.com/ticket/19184
    • 那里给出的理由都是正确的,但它们是对实现的批评,而不是模式。
    • 我不会不同意你的观点......只是添加对当前功能的观察。
    【解决方案2】:

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

    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
    

    【讨论】:

      【解决方案3】:

      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
      

      【讨论】:

        【解决方案4】:

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

        的错误

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

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

        另一种说法是它允许你不混淆返回类型(比如“这个函数返回一个 QuerySet 或 None”,这很混乱)。

        【讨论】:

          【解决方案5】:

          在 Django 文档的其他示例中查看 qs.none() 的使用位置很有用。例如,当initializing a model formset using a queryset 时,如果您希望生成的表单集为空,则给出的示例是:

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-01-08
            • 1970-01-01
            • 2011-12-28
            • 1970-01-01
            • 2015-09-26
            • 2021-02-02
            • 2018-11-14
            • 2011-04-15
            相关资源
            最近更新 更多