当我要求模型管理器获取一个对象时,当没有匹配的对象时,它会引发DoesNotExist。

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

而不是DoesNotExist,我怎么能去是None代替?


当前回答

你可以在过滤器中使用exists:

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

如果你只想知道它是否存在,这是另一种选择

其他回答

来自django docs

如果没有找到给定参数的对象,get()将引发一个DoesNotExist异常。这个异常也是模型类的一个属性。DoesNotExist异常继承自django.core.exceptions.ObjectDoesNotExist

您可以捕获异常并将None指定为go。

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

这是Django get_object_or_404方法的一个副本,只是该方法返回None。当我们必须使用only()查询来只检索某些字段时,这是非常有用的。该方法可以接受模型或查询集。

from django.shortcuts import _get_queryset


def get_object_or_none(klass, *args, **kwargs):
    """
    Use get() to return an object, or return None if object
    does not exist.
    klass may be a Model, Manager, or QuerySet object. All other passed
    arguments and keyword arguments are used in the get() query.
    Like with QuerySet.get(), MultipleObjectsReturned is raised if more than
    one object is found.
    """
    queryset = _get_queryset(klass)
    if not hasattr(queryset, 'get'):
        klass__name = klass.__name__ if isinstance(klass, type) else klass.__class__.__name__
        raise ValueError(
            "First argument to get_object_or_none() must be a Model, Manager, "
            "or QuerySet, not '%s'." % klass__name
        )
    try:
        return queryset.get(*args, **kwargs)
    except queryset.model.DoesNotExist:
        return None

从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()

我认为使用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()的信息。

在视图的不同位置处理异常可能真的很麻烦..在models.py文件中定义一个自定义模型管理器怎么样

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