问题:Django:从数据库中获取对象,如果没有匹配项,则为“无”
是否有任何Django函数可以让我从数据库中获取对象,如果没有匹配项,则为None?
现在我正在使用类似:
foo = Foo.objects.filter(bar=baz)
foo = len(foo) > 0 and foo.get() or None
但这还不是很清楚,到处都是混乱的。
回答 0
在Django 1.6中,您可以使用first()
Queryset方法。它返回查询集匹配的第一个对象,如果没有匹配的对象,则返回None。
用法:
p = Article.objects.order_by('title', 'pub_date').first()
回答 1
有两种方法可以做到这一点;
try:
foo = Foo.objects.get(bar=baz)
except model.DoesNotExist:
foo = None
或者,您可以使用包装器:
def get_or_none(model, *args, **kwargs):
try:
return model.objects.get(*args, **kwargs)
except model.DoesNotExist:
return None
这样称呼它
foo = get_or_none(Foo, baz=bar)
回答 2
要将一些示例代码添加到sorki的答案中(我将其添加为评论,但这是我的第一篇文章,并且我没有足够的声誉来发表评论),我实现了一个get_or_none自定义管理器,如下所示:
from django.db import models
class GetOrNoneManager(models.Manager):
"""Adds get_or_none method to objects
"""
def get_or_none(self, **kwargs):
try:
return self.get(**kwargs)
except self.model.DoesNotExist:
return None
class Person(models.Model):
name = models.CharField(max_length=255)
objects = GetOrNoneManager()
现在我可以这样做:
bob_or_none = Person.objects.get_or_none(name='Bob')
回答 3
您也可以尝试使用django烦人(它还有另一个有用的功能!)
用以下命令安装:
pip install django-annoying
from annoying.functions import get_object_or_None
get_object_or_None(Foo, bar=baz)
回答 4
给Foo 自定义经理。这很容易-只需将代码放入自定义管理器的函数中,在模型中设置自定义管理器,然后使用即可调用Foo.objects.your_new_func(...)
。
如果您需要通用函数(不仅要在自定义管理器中使用它,还可以在任何模型上使用它),请编写自己的函数并将其放在python路径上并导入,而不是再麻烦了。
回答 5
无论是通过管理器还是通过通用函数执行操作,您都可能希望在TRY语句中捕获“ MultipleObjectsReturned”,因为如果kwarg检索了多个对象,则get()函数将引发此问题。
基于通用功能:
def get_unique_or_none(model, *args, **kwargs):
try:
return model.objects.get(*args, **kwargs)
except (model.DoesNotExist, model.MultipleObjectsReturned), err:
return None
并在经理中:
class GetUniqueOrNoneManager(models.Manager):
"""Adds get_unique_or_none method to objects
"""
def get_unique_or_none(self, *args, **kwargs):
try:
return self.get(*args, **kwargs)
except (self.model.DoesNotExist, self.model.MultipleObjectsReturned), err:
return None
回答 6
这是helper函数的一种变体QuerySet
,如果您希望从除模型all
对象的查询集以外的查询集中获取唯一的对象(如果存在)(例如,从属于父实例):
def get_unique_or_none(model, queryset=None, *args, **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(*args, **kwargs)
except model.DoesNotExist:
return None
可以通过两种方式使用它,例如:
obj = get_unique_or_none(Model, *args, **kwargs)
如前所述obj = get_unique_or_none(Model, parent.children, *args, **kwargs)
回答 7
我认为在大多数情况下,您可以使用:
foo, created = Foo.objects.get_or_create(bar=baz)
仅在不关键要在Foo表中添加新条目的情况下(其他列将具有None / default值)
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。