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

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

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


当前回答

没有例外:

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

其他回答

我也面临着同样的问题。编写和读取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)

下面是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)

我更喜欢这种不使用异常的方法。它既可以处理多个对象,也可以不处理对象。

go_list = Content.objects.filter(name="baby")
if (len(go_list) == 1):
    go = go_list[0]
else:
    go = None # optionally do other things if there are multiple objects / no objects.

为了让事情更简单,下面是我根据这里精彩回复的输入编写的代码片段:

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 .objects. get_or_none()

从django 1.6开始,你可以像这样使用first()方法:

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