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

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

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


当前回答

我也面临着同样的问题。编写和读取try是很困难的——除非你想从模型中获取一个元素,比如@Arthur Debert的回答。因此,我的解决方案是创建一个由模型继承的Getter类:

class Getter:
    @classmethod
    def try_to_get(cls, *args, **kwargs):
        try:
            return cls.objects.get(**kwargs)
        except Exception as e:
            return None

class MyActualModel(models.Model, Getter):
    pk_id = models.AutoField(primary_key=True)
    ...

通过这种方式,我可以得到MyActualModel或None的实际元素:

MyActualModel.try_to_get(pk_id=1)

其他回答

来自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

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

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

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

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

来一片怎么样?它将解析到限制1。

go = Content.objects.filter(name="baby")[0]