问题:如何获得该对象(如果存在)或“无”(如果不存在)?
当我要求模型管理器获取一个对象时,DoesNotExist
当没有匹配的对象时,它将引发。
go = Content.objects.get(name="baby")
相反的DoesNotExist
,我怎么能有go
可以None
代替?
When I ask the model manager to get an object, it raises DoesNotExist
when there is no matching object.
go = Content.objects.get(name="baby")
Instead of DoesNotExist
, how can I have go
be None
instead?
回答 0
没有“内置”方式可以做到这一点。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')
。
There is no ‘built in’ way to do this. Django will raise the DoesNotExist exception every time.
The idiomatic way to handle this in python is to wrap it in a try catch:
try:
go = SomeModel.objects.get(foo='bar')
except SomeModel.DoesNotExist:
go = None
What I did do, is to subclass models.Manager, create a safe_get
like the code above and use that manager for my models. That way you can write: SomeModel.objects.safe_get(foo='bar')
.
回答 1
从Django 1.6开始,您可以像这样使用first()方法:
Content.objects.filter(name="baby").first()
Since django 1.6 you can use first() method like so:
Content.objects.filter(name="baby").first()
回答 2
来自Django文档
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
From django docs
get()
raises a DoesNotExist
exception if an object is not found for the given parameters. This exception is also an attribute of the model class. The DoesNotExist
exception inherits from django.core.exceptions.ObjectDoesNotExist
You can catch the exception and assign None
to go.
from django.core.exceptions import ObjectDoesNotExist
try:
go = Content.objects.get(name="baby")
except ObjectDoesNotExist:
go = None
回答 3
您可以为此创建通用函数。
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异常
You can create a generic function for this.
def get_or_none(classmodel, **kwargs):
try:
return classmodel.objects.get(**kwargs)
except classmodel.DoesNotExist:
return None
Use this like below:
go = get_or_none(Content,name="baby")
go
will be None
if no entry matches else will return the Content entry.
Note:It will raises exception MultipleObjectsReturned
if more than one entry returned for name="baby"
.
You should handle it on the data model to avoid this kind of error but you may prefer to log it at run time like this:
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
回答 4
回答 5
为了使事情变得更容易,以下是我编写的代码的片段,这些代码基于来自此处精彩答复的输入:
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()
To make things easier, here is a snippet of the code I wrote, based on inputs from the wonderful replies here:
class MyManager(models.Manager):
def get_or_none(self, **kwargs):
try:
return self.get(**kwargs)
except ObjectDoesNotExist:
return None
And then in your model:
class MyModel(models.Model):
objects = MyManager()
That’s it.
Now you have MyModel.objects.get() as well as MyModel.objetcs.get_or_none()
回答 6
您可以使用exists
过滤器:
Content.objects.filter(name="baby").exists()
#returns False or True depending on if there is anything in the QS
如果您只想知道它是否存在,则只是一个选择
you could use exists
with a filter:
Content.objects.filter(name="baby").exists()
#returns False or True depending on if there is anything in the QS
just an alternative for if you only want to know if it exists
回答 7
在视图中的不同点处理异常可能真的很麻烦。.如何在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
Handling exceptions at different points in your views could really be cumbersome..What about defining a custom Model Manager, in the models.py file, like
class ContentManager(model.Manager):
def get_nicely(self, **kwargs):
try:
return self.get(kwargs)
except(KeyError, Content.DoesNotExist):
return None
and then including it in the content Model class
class Content(model.Model):
...
objects = ContentManager()
In this way it can be easily dealt in the views i.e.
post = Content.objects.get_nicely(pk = 1)
if post:
# Do something
else:
# This post doesn't exist
回答 8
这是您可能不想重新实现的那些烦人的功能之一:
from annoying.functions import get_object_or_None
#...
user = get_object_or_None(Content, name="baby")
It’s one of those annoying functions that you might not want to re-implement:
from annoying.functions import get_object_or_None
#...
user = get_object_or_None(Content, name="baby")
回答 9
如果您想要一个不涉及异常处理,条件语句或Django 1.6+要求的简单的单行解决方案,请执行以下操作:
x = next(iter(SomeModel.objects.filter(foo='bar')), None)
If you want a simple one-line solution that doesn’t involve exception handling, conditional statements or a requirement of Django 1.6+, do this instead:
x = next(iter(SomeModel.objects.filter(foo='bar')), None)
回答 10
我认为使用它不是一个坏主意 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()的更多信息。
I think it isn’t bad idea to use 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)
This example is equivalent to:
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.")
You can read more about get_object_or_404() in django online documentation.
回答 11
从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()
From django 1.7 onwards you can do like:
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):
...
The advantage of “MyQuerySet.as_manager()” is that both of the following will work:
MyModel.objects.filter(...).get_or_none()
MyModel.objects.get_or_none()
回答 12
这是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)
Here’s a variation on the helper function that allows you to optionally pass in a QuerySet
instance, in case you want to get the unique object (if present) from a queryset other than the model’s all
objects queryset (e.g. from a subset of child items belonging to a parent instance):
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
This can be used in two ways, e.g.:
obj = get_unique_or_none(Model, **kwargs)
as previosuly discussed
obj = get_unique_or_none(Model, parent.children, **kwargs)
回答 13
毫无exceptions:
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中使用异常有一些参数。一方面,“请求宽恕比允许更容易”。尽管我同意这一点,但我认为应该保留一个exceptions,这个exceptions,并且“理想情况”应该继续存在而不会碰到一个exceptions。
Without exception:
if SomeModel.objects.filter(foo='bar').exists():
x = SomeModel.objects.get(foo='bar')
else:
x = None
Using an exception:
try:
x = SomeModel.objects.get(foo='bar')
except SomeModel.DoesNotExist:
x = None
There is a bit of an argument about when one should use an exception in python. On the one hand, “it is easier to ask for forgiveness than for permission”. While I agree with this, I believe that an exception should remain, well, the exception, and the “ideal case” should run without hitting one.
回答 14
我们可以使用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
We can use Django builtin exception which attached to the models named as .DoesNotExist
. So, we don’t have to import ObjectDoesNotExist
exception.
Instead doing:
from django.core.exceptions import ObjectDoesNotExist
try:
content = Content.objects.get(name="baby")
except ObjectDoesNotExist:
content = None
We can do this:
try:
content = Content.objects.get(name="baby")
except Content.DoesNotExist:
content = None
回答 15
这是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
This is a copycat from Django’s get_object_or_404 except that the method returns None. This is extremely useful when we have to use only()
query to retreive certain fields only. This method can accept a model or a queryset.
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
回答 16
也许使用更好:
User.objects.filter(username=admin_username).exists()
Maybe is better you use:
User.objects.filter(username=admin_username).exists()