获取对象时“匹配查询不存在”如何处理

问题描述 投票:0回答:4

当我想使用 get() 函数选择对象时

personalProfile = World.objects.get(ID=personID)

如果 get 函数没有返回查找值,则“匹配查询不存在”。发生错误。

如果我不需要这个错误,我将使用 try 和 except 函数

try:
   personalProfile = World.objects.get(ID=personID)
except:
   pass

但我认为这不是我使用以来的最好方法

except:
      pass

请推荐一些想法或代码示例来解决这个问题

django python-2.7 django-views
4个回答
15
投票

这取决于你想做什么,如果它不存在..

get_object_or_404

在给定的模型管理器上调用 get(),但它会引发 Http404 而不是模型的DoesNotExist 异常。

get_object_or_404(World, ID=personID)

这与您当前执行的 try except 代码非常接近。

否则还有

get_or_create
:

personalProfile, created = World.objects.get_or_create(ID=personID)

尽管如此,如果您选择继续当前的方法,至少要确保 except 本地化为正确的错误,然后根据需要执行某些操作

try:
   personalProfile = World.objects.get(ID=personID)
except MyModel.DoesNotExist:
    raise Http404("No MyModel matches the given query.")

上面的 try/ except 句柄类似于 get_object_or_404 文档中的内容...


4
投票

get_or_none()
功能已被提议,现在多个。拒绝通知是“功能蔓延”,您可能同意也可能不同意。该功能存在于 first()
 查询集方法中,但语义略有不同。
但首先要说的是:

当未找到

World.DoesNotExist

对象时,管理器抛出

ObjectDoesNotExist
World
的专门子类:

try: personalProfile = World.objects.get(ID=personID) except World.DoesNotExist: pass

还有 

get_object_or_404()

,当未找到对象时会引发 
Http404 异常。

您也可以自己滚动

get_or_none()

。一个可能的实现可能是:


def get_or_none(queryset, *args, **kwargs): try: return queryset.get(*args, **kwargs) except ObjectDoesNotExist: return None

请注意,当找到多个匹配对象时,这仍然会引发 
MultipleObjectsReturned

。如果您始终想要第一个对象而不管其他对象,您可以使用

first()
进行简化,当查询集为空时,它会返回
None

def get_or_none(queryset, *args, **kwargs): return queryset.filter(*args, **kwargs).first()

但是请注意,为了使其可靠地工作,您需要对象的正确顺序,因为在存在多个对象的情况下
first()

可能是不确定的(它可能返回用于过滤查询的数据库索引中的第一个对象,并且索引和基础表都不需要排序,甚至不需要有可重复的顺序)。


但是,只有当要检索的对象的使用对于后续程序流程来说是严格可选的时,才使用两者。当未能检索对象是一个错误时,请使用

get_object_or_404()

。当一个对象不存在而应该创建时,请使用

get_or_create()
。在这些情况下,两者都更适合简化程序流程。


0
投票
alasdair

提到的,您可以使用内置的 first() 方法。 如果对象存在则返回该对象,如果不存在则返回 None personalProfile = World.objects.filter(ID=personID).first()



0
投票
World.objects.get_or_create(ID=personID)

感谢@Sayse

© www.soinside.com 2019 - 2024. All rights reserved.