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

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

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


当前回答

我使用的是Django 2.2.16。这就是我解决这个问题的方法:

from typing import Any

from django.core.exceptions import ObjectDoesNotExist
from django.db import models
from django.db.models.base import ModelBase
from django.db.models.manager import Manager


class SManager(Manager):
    def get_if_exist(self, *args: Any, **kwargs: Any):
        try:
            return self.get(*args, **kwargs)
        except ObjectDoesNotExist:
            return None


class SModelBase(ModelBase):
    def _prepare(cls):
        manager = SManager()
        manager.auto_created = True
        cls.add_to_class("objects", manager)

        super()._prepare()

    class Meta:
        abstract = True


class SModel(models.Model, metaclass=SModelBase):
    managers = False

    class Meta:
        abstract = True

之后,在每个模型中,你只需要导入:

from custom.models import SModel


class SUser(SModel):
    pass

在视图中,你可以这样调用:

SUser.objects.get_if_exist(id=1)

其他回答

您可以为此创建一个通用函数。

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"返回了多个条目,将引发异常MultipleObjectsReturned。

你应该在数据模型上处理它以避免这种错误,但你可能更喜欢在运行时像这样记录它:

def get_or_none(classmodel, **kwargs):
    try:
        return classmodel.objects.get(**kwargs)
    except classmodel.MultipleObjectsReturned as e:
        print('ERR====>', e)

    except classmodel.DoesNotExist:
        return None

下面是helper函数的一个变体,它允许你有选择地传入一个QuerySet实例,以防你想从模型的所有对象QuerySet之外的QuerySet中获得唯一的对象(如果存在)(例如,从属于父实例的子项的子集中):

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

这可以用在两种情况下,例如:

obj = get_unique_or_none(Model, **kwargs),如前所述 obj = get_unique_or_none(模型,父。孩子,* * kwargs)

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

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

这是一个讨厌的函数,你可能不想重新实现:

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

没有例外:

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

使用异常:

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

关于在python中什么时候应该使用异常有一点争论。一方面,“请求原谅比请求允许容易”。虽然我同意这一点,但我认为应该保留一个异常,好吧,异常,并且“理想情况”应该运行而不碰到异常。