Answers:
没有“内置”方式可以做到这一点。Django每次都会引发DidNotExist异常。在python中处理此问题的惯用方式是将其包装在try catch中:
try:
go = SomeModel.objects.get(foo='bar')
except SomeModel.DoesNotExist:
go = None
我所做的就是将模型.Manager子类化,创建safe_get
类似于上面的代码,并将该经理用于我的模型。这样,您可以编写:SomeModel.objects.safe_get(foo='bar')
。
SomeModel.objects.filter(foo='bar').first()
此方法返回第一个匹配项,或者返回None。如果有多个实例,它不会失败queryset.get()
filter().first()
我认为应该采取例外措施。
从Django 1.6开始,您可以像这样使用first()方法:
Content.objects.filter(name="baby").first()
get()
DoesNotExist
如果找不到给定参数的对象,则会引发异常。此异常也是模型类的属性。在DoesNotExist
从异常继承django.core.exceptions.ObjectDoesNotExist
您可以捕获异常并分配None
去。
from django.core.exceptions import ObjectDoesNotExist
try:
go = Content.objects.get(name="baby")
except ObjectDoesNotExist:
go = None
您可以这样操作:
go = Content.objects.filter(name="baby").first()
现在go变量可以是您想要的对象,也可以是None
参考:https : //docs.djangoproject.com/en/1.8/ref/models/querysets/#django.db.models.query.QuerySet.first
为了使事情变得更容易,以下是我编写的代码的片段,这些代码基于来自此处精彩答复的输入:
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.objetcs.get_or_none()
您可以使用exists
过滤器:
Content.objects.filter(name="baby").exists()
#returns False or True depending on if there is anything in the QS
如果您只想知道它是否存在,则只是一个选择
Note: If you only want to determine if at least one result exists (and don’t need the actual objects), it’s more efficient to use exists().
exists()
将与with if
子句一起使用,从而导致对数据库的双重打击。我仍然会保留评论,以免对他人有所帮助。
在视图中的不同点处理异常可能真的很麻烦。.如何在models.py文件中定义自定义模型管理器,如
class ContentManager(model.Manager):
def get_nicely(self, **kwargs):
try:
return self.get(kwargs)
except(KeyError, Content.DoesNotExist):
return None
然后将其包含在内容模型类中
class Content(model.Model):
...
objects = ContentManager()
这样可以很容易地在视图中处理,即
post = Content.objects.get_nicely(pk = 1)
if post:
# Do something
else:
# This post doesn't exist
return self.get(**kwargs)
使其对我有用。并不是说答案有什么问题,这只是对尝试在更高版本(或任何其他使它无法使用的版本)中使用的人的一个提示。
我认为使用它不是一个坏主意 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.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()
这是helper函数的一种变体QuerySet
,如果您希望从除模型all
对象的查询集以外的查询集中获取唯一的对象(如果存在)(例如,从属于父实例):
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(Model, parent.children, **kwargs)
毫无例外:
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中使用异常有一些争论。一方面,“请求宽恕比允许更容易”。尽管我同意这一点,但我认为应该保留一个例外,这个例外,并且“理想情况”应该继续存在而不会碰到一个例外。
我们可以使用Django内置异常,该异常附加到名为的模型上.DoesNotExist
。因此,我们不必导入ObjectDoesNotExist
异常。
而是这样做:
from django.core.exceptions import ObjectDoesNotExist
try:
content = Content.objects.get(name="baby")
except ObjectDoesNotExist:
content = None
我们可以完成这个:
try:
content = Content.objects.get(name="baby")
except Content.DoesNotExist:
content = 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
也许使用更好:
User.objects.filter(username=admin_username).exists()