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

时间:2015-10-14 07:44:40

标签: django python-2.7 django-views

当我想用像(

)这样的get()函数选择对象时
personalProfile = World.objects.get(ID=personID)

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

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

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

但我认为这不是自从我使用

以来最好的方法
except:
      pass

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

2 个答案:

答案 0 :(得分:10)

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

Theres get_object_or_404

  

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

get_object_or_404(World, ID=personID)

除了您目前的代码之外,这与try非常接近。

除此之外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的文档中的内容...

答案 1 :(得分:2)

现在,get_or_none()功能已proposedmultiple times。拒绝通知是 feature creep ,您可能会或可能不会同意。在first() queryset方法中存在功能 - 语义略有不同。

但首先要做的事情是:

当找不到World.DoesNotExist对象时,经理会抛出WorldObjectDoesNotExist的专门子类:

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()。在这些情况下,两者都更适合简化程序流程。