如果存在该对象,该如何获取;如果该对象不存在,该如何获取?

当我让模型pipe理器获得一个对象时,当没有匹配的对象时,它会引发DoesNotExist

 go = Content.objects.get(name="baby") 

而不是DoesNotExist ,我怎么能成为None而不是?

没有“内置”的方式来做到这一点。 Django每次都会引发DoesNotExistexception。 在Python中处理这个问题的惯用方法是将其封装在try catch中:

 try: go = SomeModel.objects.get(foo='bar') except SomeModel.DoesNotExist: go = None 

我所做的就是将models.Manager创build子类,像上面的代码一样创build一个safe_get ,并将该pipe理器用于我的模型。 这样你可以写: SomeModel.objects.safe_get(foo='bar')

因为django 1.6你可以使用first()方法:

 Content.objects.filter(name="baby").first() 

从Django的文档

如果找不到给定参数的对象,则get()会引发一个DoesNotExistexception。 这个exception也是模型类的一个属性。 DoesNotExistexceptioninheritance自django.core.exceptions.ObjectDoesNotExist

你可以捕捉到exception,并指定None去。

 from django.core.exceptions import ObjectDoesNotExist try: go = Content.objects.get(name="baby") except ObjectDoesNotExist: go = None 

你可以为此创build一个通用函数。

 def get_or_none(classmodel, **kwargs): try: return classmodel.objects.get(**kwargs) except classmodel.DoesNotExist: return None 

使用如下所示:

 go = get_or_none(Content,name="baby") 

如果没有条目匹配,则go将是None,否则将返回Content条目。

注意:如果多于一个入口返回name =“baby”,将引发exceptionMultipleObjectsReturned

为了使事情更容易,下面是我写的代码的一小部分,根据这里精彩的答复的input:

 class MyManager(models.Manager): def get_or_none(self, **kwargs): try: return self.get(**kwargs) except ObjectDoesNotExist: return None 

然后在你的模型中:

 class MyModel(models.Model): objects = MyManager() 

而已。 现在你有MyModel.objects.get()以及MyModel.objetcs.get_or_none()

你可以使用exists与filter:

 Content.objects.filter(name="baby").exists() #returns False or True depending on if there is anything in the QS 

只是一个select,如果你只想知道它是否存在

这是您可能不希望重新实现的令人讨厌的function之一:

 from annoying.functions import get_object_or_None #... user = get_object_or_None(Content, name="baby") 

你可以这样做:

 go = Content.objects.filter(name="baby").first() 

现在variables可以是你想要的对象或None

参考: https : //docs.djangoproject.com/en/1.8/ref/models/querysets/#django.db.models.query.QuerySet.first

处理视图中不同点的exception真的很麻烦。关于如何在models.py文件中定义一个自定义模型pipe理器

 class ContentManager(model.Manager): def get_nicely(self, **kwargs): try: return self.get(kwargs) except(KeyError, Content.DoesNotExist): return None 

然后将其包含在内容Model类中

 class Content(model.Model): ... objects = ContentManager() 

通过这种方式,可以很容易地处理的意见,即

 post = Content.objects.get_nicely(pk = 1) if post: # Do something else: # This post doesn't exist 

如果你想要一个简单的单行解决scheme,不涉及exception处理,条件语句或者Django 1.6+的需求,那就这样做:

 x = next(iter(SomeModel.objects.filter(foo='bar')), None) 

以下是助手函数的一个变体,您可以select传入QuerySet实例,以防万一您希望从模型的all对象查询集以外的查询集(例如,从属于子项的子集中获取唯一对象到一个父实例):

 def get_unique_or_none(model, queryset=None, **kwargs): """ Performs the query on the specified `queryset` (defaulting to the `all` queryset of the `model`'s default manager) and returns the unique object matching the given keyword arguments. Returns `None` if no match is found. Throws a `model.MultipleObjectsReturned` exception if more than one match is found. """ if queryset is None: queryset = model.objects.all() try: return queryset.get(**kwargs) except model.DoesNotExist: return None 

这可以以两种方式使用,例如:

  1. obj = get_unique_or_none(Model, **kwargs)
  2. obj = get_unique_or_none(Model, parent.children, **kwargs)

毫无例外:

 if SomeModel.objects.filter(foo='bar').exists(): x = SomeModel.objects.get(foo='bar') else: x = None 

使用exception:

 try: x = SomeModel.objects.get(foo='bar') except SomeModel.DoesNotExist: x = None 

关于何时应该在python中使用exception有一些争论。 一方面,“请求宽恕比允许要容易”。 虽然我同意这一点,但我认为应该保留一个例外,那就是例外,“理想的情况”应该不会碰到一个例外。

从Django 1.7开始,你可以这样做:

 class MyQuerySet(models.QuerySet): def get_or_none(self, **kwargs): try: return self.get(**kwargs) except self.model.DoesNotExist: return None class MyBaseModel(models.Model): objects = MyQuerySet.as_manager() class MyModel(MyBaseModel): ... class AnotherMyModel(MyBaseModel): ... 

“MyQuerySet.as_manager()”的优点是以下两个方法都可以工作:

 MyModel.objects.filter(...).get_or_none() MyModel.objects.get_or_none() 

我们可以使用Django内置的exception附加到名为.DoesNotExist的模型。 所以,我们不必导入ObjectDoesNotExistexception。

而是做:

 from django.core.exceptions import ObjectDoesNotExist try: content = Content.objects.get(name="baby") except ObjectDoesNotExist: content = None 

我们做得到:

 try: content = Content.objects.get(name="baby") except Content.DoesNotExist: content = None 

我认为使用get_object_or_404()是不错的主意

 from django.shortcuts import get_object_or_404 def my_view(request): my_object = get_object_or_404(MyModel, pk=1) 

这个例子相当于:

 from django.http import Http404 def my_view(request): try: my_object = MyModel.objects.get(pk=1) except MyModel.DoesNotExist: raise Http404("No MyModel matches the given query.") 

您可以在django在线文档中阅读关于get_object_or_404()的更多信息。