如果 Django 中存在该对象,我如何获取该对象;如果该对象不存在,我如何获取 None?
当我要求模型管理器获取一个对象时,如果没有匹配的对象,它会引发 DoesNotExist
。
go = Content.objects.get(name="baby")
我怎样才能让 go
变成 None
而不是 DoesNotExist
呢?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(24)
没有“内置”方法可以做到这一点。 Django 每次都会引发
DoesNotExist
异常。在 python 中处理这个问题的惯用方法是将其包装在 try catch 中:
我所做的是子类
models.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:
What I did do, is to subclass
models.Manager
, create asafe_get
like the code above and use that manager for my models. That way you can write:SomeModel.objects.safe_get(foo='bar')
.从 Django 1.6 开始,您可以使用 first() 方法,如下所示:
如果没有对象符合条件,则返回
None
。如果多个对象符合条件,则返回第一个匹配项(不会引发错误)。Since Django 1.6 you can use first() method like so:
If no objects match the criteria, then
None
is returned. If more than one object match the criteria, then the first match is returned (no error is raised).您可以为此创建一个通用函数。
使用如下所示:
如果没有条目匹配,则
go
将为None
,否则将返回内容条目。注意:如果
name="baby"
返回多个条目,则会引发异常MultipleObjectsReturned
。您应该在数据模型上处理它以避免这种错误,但您可能更喜欢在运行时记录它,如下所示:
You can create a generic function for this.
Use this like below:
go
will beNone
if no entry matches else will return the Content entry.Note:It will raises exception
MultipleObjectsReturned
if more than one entry returned forname="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:
来自 django 文档
您可以捕获异常并分配
None
去。From django docs
You can catch the exception and assign
None
to go.你可以这样做:
现在 go 变量可以是你想要的对象,也可以是 None
参考: https://docs.djangoproject.com/en/1.8/ref/models/querysets/#django.db.models.query.QuerySet.first
You can do it this way:
Now go variable could be either the object you want or None
Ref: https://docs.djangoproject.com/en/1.8/ref/models/querysets/#django.db.models.query.QuerySet.first
为了使事情变得更容易,这里是我编写的代码片段,基于此处精彩回复的输入:
然后在您的模型中:
就是这样。
现在你有了 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:
And then in your model:
That's it.
Now you have MyModel.objects.get() as well as MyModel.objetcs.get_or_none()
您可以将
exists
与过滤器一起使用:如果您只想知道它是否存在,这只是一个替代方案
you could use
exists
with a filter:just an alternative for if you only want to know if it exists
这是您可能不想重新实现的烦人的函数之一:
It's one of those annoying functions that you might not want to re-implement:
也许你使用更好:
Maybe is better you use:
在视图中的不同点处理异常可能真的很麻烦。在 models.py 文件中定义自定义模型管理器怎么样,
然后将其包含在内容模型类中
这样就可以在视图中轻松处理它IE
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
and then including it in the content Model class
In this way it can be easily dealt in the views i.e.
我认为使用
get_object_or_404()
这个例子相当于:
您可以阅读有关 get_object_or_404() 。
I think it isn't bad idea to use
get_object_or_404()
This example is equivalent to:
You can read more about get_object_or_404() in django online documentation.
如果您想要一个简单的单行解决方案,不涉及异常处理、条件语句或 Django 1.6+ 的要求,请改为执行以下操作:
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:
从 django 1.7 开始,您可以这样做:
“MyQuerySet.as_manager()”的优点是以下两者都可以工作:
From django 1.7 onwards you can do like:
The advantage of "MyQuerySet.as_manager()" is that both of the following will work:
我使用 Django 2.2.16。这就是我解决这个问题的方法:
之后,在每个模型中,您只需要导入:
在
views
中,您可以像这样调用:I use Django 2.2.16. And this is how I solve this problem:
And after that, in every models, you just need to import in:
And in
views
, you can call like this:这是 Django 的 get_object_or_404 的模仿者,只不过该方法返回 None 。当我们必须使用
only()
查询来仅检索某些字段时,这非常有用。此方法可以接受模型或查询集。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.这是辅助函数的变体,如果您想从模型的
all< 之外的查询集中获取唯一对象(如果存在),它允许您选择传入
QuerySet
实例。 /code> 对象查询集(例如,来自属于父实例的子项子集):这可以通过两种方式使用,例如:
obj = get_unique_or_none(Model, **kwargs)
如前所述obj = get_unique_or_none(模型,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'sall
objects queryset (e.g. from a subset of child items belonging to a parent instance):This can be used in two ways, e.g.:
obj = get_unique_or_none(Model, **kwargs)
as previosuly discussedobj = get_unique_or_none(Model, parent.children, **kwargs)
无例外:
使用异常:
关于何时应该在 python 中使用异常存在一些争论。一方面,“请求原谅比请求许可更容易”。虽然我同意这一点,但我相信例外应该保留,好吧,例外,并且“理想情况”应该运行而不会遇到例外。
Without exception:
Using an exception:
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.
我们可以使用 Django 内置异常,它附加到名为
.DoesNotExist
的模型上。因此,我们不必导入ObjectDoesNotExist
异常。相反,
我们可以这样做:
We can use Django builtin exception which attached to the models named as
.DoesNotExist
. So, we don't have to importObjectDoesNotExist
exception.Instead doing:
We can do this:
我也面临着同样的问题。当您想从模型中获取元素时,每次都很难编写和读取
try- except
,就像 @Arthur Debert 的答案一样。所以,我的解决方案是创建一个由模型继承的Getter
类:通过这种方式,我可以获得
MyActualModel
或None
的实际元素代码>:I was facing with the same problem too. It's hard to write and read
try-except
for each time when you want to get an element from your model as in @Arthur Debert's answer. So, my solution is to create anGetter
class which is inherited by the models:In this way, I can get the actual element of
MyActualModel
orNone
:简单的方法:
if query.exists():
做某事...
或者
如果 query.exists() 为 False:
做某事...
Simple way:
if query.exists():
do something....
or
if query.exists() is False:
do something...
我更喜欢这种不使用异常的方法。它还可以处理多个对象以及不处理任何对象。
I prefer this method without using exceptions. It also handles multiple objects as well as no objects.
如果有这样的事情怎么办?
What if something like this?
正如其他答案中提到的,您可以使用
filter(**kwargs).first()
此方法的问题是,如果查询返回多个对象。这可能并不总是令人满意的。假设您有以下数据库表
Person.objects.filter(last_name="Wayans").first()
将始终返回 Keenen Wayans 。用户永远不会知道还有其他“Wayans”
如果你不喜欢这个,下面是我对 Django 快捷方法的重新实现 get_object_or_404。如果没有找到对象,则返回
None
,但如果查询返回多个对象,则抛出 MultipleObjectsReturned 异常。我宁愿处理 MultipleObjectsReturned 异常,而不是向用户返回虚假值。在名为
shortcuts.py
的单独文件中,创建一个名为 get_object_or_none 的方法。然后在views.py中
As it has been mentioned in other answers, you can use
filter(**kwargs).first()
The issue with this method is it never throws a MultipleObjectsReturned error if the query returns multiple objects. This may not always be desirable. Assume you have the following database table
Person.objects.filter(last_name="Wayans").first()
will always return Keenen Wayans. The user will never know there are other 'Wayans'
If you don't like this, below is my reimplementation of Django's shortcut method get_object_or_404. If no object is found, it returns
None
, but if the query returns multiple objects, it throws a MultipleObjectsReturned exception. I would rather handle MultipleObjectsReturned exception, instead of returning a bogus value to the user.In a separate file called
shortcuts.py
, create a method called get_object_or_none.Then in
views.py
切片怎么样?它将解析到限制 1。
How about a slice? It will parse to a limit 1.