检查特定实例是不是存在的更好选择 django

Posted

技术标签:

【中文标题】检查特定实例是不是存在的更好选择 django【英文标题】:Better option to check if a particular instance exists django检查特定实例是否存在的更好选择 django 【发布时间】:2015-12-27 04:46:55 【问题描述】:

这两者中的哪一个是检查实例是否存在的更好和更有效的选择。最多只能返回一条记录。

1) 使用过滤器选项,看看是否存在:

x = MyObject.objects.filter(someField=someValue).count()
if x:
    #Instance exists

2) 使用 get 并检查异常:

try:
    x = MyObject.objects.get(someField=someValue)
except MyObject.DoesNotExist:
    #Do Something

上面提到的哪种方法更高效或更“Djangoic”?

【问题讨论】:

【参考方案1】:

这取决于你想要获得一条记录还是多条记录

如果您需要以 Python 方式检查是否存在,则需要将它们包含在 try 和 except 块中

try: 
  instance = MyModel.objects.all().get(condition) 
  #can continue to use instance  
except MyModel.DoesNotExist: 
  #do something if model does not exist  
  Print(“model instances doesn't exist”)  

如果您使用过滤器或获取所有实例

instances = MyModel.objects.all().filter(condition)  
If instances: 
  #if list of instances have Atleast one instance  
  Pass 
else: 
  #do something if model does not exist  
  Print(“model instances doesn't exist”)

【讨论】:

【参考方案2】:

甚至更好的方法是使用.exists() 来检查特定实例是否存在。

MyObject.objects.filter(someField=someValue).exists() # return True/False

来自.exists() docs:

如果 QuerySet 包含任何结果,则返回 True,如果返回 False 不是。这尝试以最简单和最快的方式执行查询 可能, 但它确实执行与普通查询几乎相同的查询 QuerySet 查询。

exists() 对于与两个对象成员相关的搜索很有用 一个 QuerySet 和一个 QuerySet 中是否存在任何对象, 特别是在大型 QuerySet 的上下文中。

文档中的一些示例:

示例1:查找具有唯一字段的模型是否是QuerySet的成员

查找模型是否具有唯一性的最有效方法 字段(例如primary_key)是QuerySet的成员是:

entry = Entry.objects.get(pk=123)

if some_queryset.filter(pk=entry.pk).exists(): # faster
    print("Entry contained in queryset")

这将比以下需要评估和 遍历整个查询集:

if entry in some_queryset: # slower 
   print("Entry contained in QuerySet")

示例 2:查找查询集是否包含任何项目

要查找查询集是否包含任何项目,请使用以下方法

if some_queryset.exists(): # faster
    print("There is at least one object in some_queryset")

将比:

if some_queryset: # slower
    print("There is at least one object in some_queryset")

...但不是很大程度(因此需要一个大的查询集 效率提升)。

如果我也想使用该对象(如果存在)怎么办?

如果您还想使用该对象(如果它存在),那么使用.exists() 效率不高,因为您将执行 2 个查询。第一个查询是检查是否存在,第二个查询是获取对象。

【讨论】:

那么使用异常是个坏主意吗? @AswinMurugesh 我实际上更喜欢用鸭子打字来进行单实例查找,请参阅我的答案 @AswinMurugesh 如果您只需要检查实例是否存在,那么这是最好的方法。文档中甚至建议使用此方法来检查实例是否存在。 请注意,使用MyObject.objects.filter(foo='bar').exists() 仍会从数据库中获取整个对象及其所有字段。使用MyObject.objects.only('foo').filter(foo='bar').exists() 可以更快地更改查询以仅获取被过滤的同一列。如果您要过滤的字段是主键或有索引,这将特别有用,因为它允许数据库优化为仅索引查询。 YMMV 取决于模型底层的特定数据库。【参考方案3】:

在尝试查找是否存在单个实例时,我不喜欢 exists 解决方案。

在这种情况下,我会选择 duck typing(你的第二个选项),因为它更像是 pythonic:

try:
    instance = MyModel.objects.get(id=1)
except MyModel.DoesNotExist:
    print "Too bad"
else:
    instance.do_something()

【讨论】:

【参考方案4】:

我会说像这样在过滤后的查询集上使用 exists(),

MyObject.objects.filter(someField=someValue).exists()

Django 文档大多鼓励使用 exists(),而不是替代方法。您可以在此处阅读更多相关信息。

https://docs.djangoproject.com/en/1.8/ref/models/querysets/

【讨论】:

以上是关于检查特定实例是不是存在的更好选择 django的主要内容,如果未能解决你的问题,请参考以下文章

Django:检查实例是不是存在于用户数据库中并保存到应用模型数据库

如何检查项目是不是存在于多个数组中

Django:如何检查自定义小部件定义中是不是存在字段错误?

选择一个有效的选择 Django Filtered Drop Down Menu

有没有更好的选择来检查子字符串是不是为数字?

Django Queryset 过滤器检查相关对象是不是存在