当我要求模型管理器获取一个对象时,当没有匹配的对象时,它会引发DoesNotExist。
go = Content.objects.get(name="baby")
而不是DoesNotExist,我怎么能去是None代替?
当我要求模型管理器获取一个对象时,当没有匹配的对象时,它会引发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)
其他回答
我认为使用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()的信息。
如果你想要一个简单的单行解决方案,不涉及异常处理、条件语句或Django 1.6+的要求,可以这样做:
x = next(iter(SomeModel.objects.filter(foo='bar')), 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)
从django 1.6开始,你可以像这样使用first()方法:
Content.objects.filter(name="baby").first()
来一片怎么样?它将解析到限制1。
go = Content.objects.filter(name="baby")[0]