【发布时间】:2012-12-26 17:27:12
【问题描述】:
刚刚在django docs看到这个
调用 none() 将创建一个从不返回任何对象的查询集 访问结果时不会执行任何查询。一个 qs.none() queryset 是 EmptyQuerySet 的一个实例。
我构建了很多 CRUD 应用程序(惊喜),但我想不出我需要使用 none() 的情况。
为什么要返回一个 EmptyQuerySet?
【问题讨论】:
刚刚在django docs看到这个
调用 none() 将创建一个从不返回任何对象的查询集 访问结果时不会执行任何查询。一个 qs.none() queryset 是 EmptyQuerySet 的一个实例。
我构建了很多 CRUD 应用程序(惊喜),但我想不出我需要使用 none() 的情况。
为什么要返回一个 EmptyQuerySet?
【问题讨论】:
通常在您需要提供QuerySet,但没有提供的情况下 - 例如调用方法或提供给模板。
优点是如果你知道没有结果(或不想要结果)而你仍然需要一个,none() 不会访问数据库。
举一个不切实际的例子,假设您有一个 API,您可以在其中查询您的权限。如果帐户尚未确认,因为您已经拥有Account 对象并且您可以看到account.is_activated 是False,您可以跳过检查数据库的权限,只需使用Permission.objects.none()
【讨论】:
如果您想追加到查询集但希望以空开头 类似于我们实例化一个空列表开始但逐渐向它附加有意义的值的情况 例子..
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
【讨论】:
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
【讨论】:
另一个很好的用例是如果某些调用方法想要调用.values_list() 或类似的结果。如果该方法返回 None,您将收到类似
AttributeError: 'list' object has no attribute 'values_list'
但如果您的子句返回 MyModel.objects.none() 而不是 None,调用代码会很高兴,因为返回的数据是空查询集而不是 None 对象。
另一种说法是它允许你不混淆返回类型(比如“这个函数返回一个 QuerySet 或 None”,这很混乱)。
【讨论】:
在 Django 文档的其他示例中查看 qs.none() 的使用位置很有用。例如,当initializing a model formset using a queryset 时,如果您希望生成的表单集为空,则给出的示例是:
formset = AuthorFormSet(queryset=Author.objects.none())
【讨论】: