Python 什么';这是处理Django';s.get?

Python 什么';这是处理Django';s.get?,python,django,Python,Django,每当我这样做: thepost = Content.objects.get(name="test") 当找不到任何东西时,它总是抛出一个错误。 我怎么处理 try: thepost = Content.objects.get(name="test") except Content.DoesNotExist: thepost = None 通常,使用Django快捷方式函数而不是直接使用API更有用: from django.shortcuts import get_objec

每当我这样做:

thepost = Content.objects.get(name="test")
当找不到任何东西时,它总是抛出一个错误。 我怎么处理

try:
    thepost = Content.objects.get(name="test")
except Content.DoesNotExist:
    thepost = None

通常,使用Django快捷方式函数而不是直接使用API更有用:

from django.shortcuts import get_object_or_404

thepost = get_object_or_404(Content, name='test')
try:
    thepost = Content.objects.get(name="test")
except Content.DoesNotExist:
    thepost = None
很明显,如果找不到对象,这将抛出404错误,如果成功,代码将继续。

捕获异常

try:
    thepost = Content.objects.get(name="test")
except Content.DoesNotExist:
    thepost = None
或者,您可以进行筛选,如果没有匹配项,则将返回空列表

posts = Content.objects.filter(name="test")
if posts:
    # do something with posts[0] and see if you want to raise error if post > 1

你也可以抓住一个普通的实干家。根据

提出一个伟大的目标:

from django.http import Http404

def detail(request, poll_id):
    try:
        p = Poll.objects.get(pk=poll_id)
    except Poll.DoesNotExist:
        raise Http404
    return render_to_response('polls/detail.html', {'poll': p})

在视图中的不同点处理异常可能非常麻烦..在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 != None:
    # Do something
else:
    # This post doesn't exist

另一种写作方式:

try:
    thepost = Content.objects.get(name="test")
except Content.DoesNotExist:
    thepost = None
简单地说:

thepost = Content.objects.filter(name="test").first()

请注意,两者并非完全相同。管理器方法
get
不仅会在没有您要查询的记录的情况下引发异常,还会在找到多个记录的情况下引发异常。当有多条记录时,使用
first
可能会通过返回第一条记录而导致业务逻辑失败。

基本上有两种方法可以做到这一点。第一种方法更为冗长,因为它不使用任何
快捷方式

from django.http import Http404
from .models import Content    


try:
    thepost = Content.objects.get(name="test")
except Content.DoesNotExist:
    raise Http404("Content does not exist")
现在,由于这种操作(即获取对象或在不存在对象的情况下提升404)在Web开发中非常常见,Django提供了一种称为的快捷方式,该快捷方式将
get()
请求的对象,或者在找不到对象的情况下提升
Http404

from django.shortcuts import get_object_or_404
from .models import Content


thepost = get_object_or_404(Content, name="test")


同样,对于对象列表,您可以使用函数使用
filter()
而不是
get()
,如果返回的列表为空,将引发
Http404

在这种情况下,例外情况是
Content.DoesNotExist
,如果您想在找不到对象的情况下继续(例如,不抛出404错误,如我的示例中所示),此代码结构非常有用。请参见它的工作方式。你的问题是什么?如何编写
try
语句?当get()只会引发异常时,为什么要分配一个空的Queryset?try/catch-first方法通常要好得多,在正常的“工作流”中使用异常不是一种好的做法。在本例中,很容易理解,但如果您开始使用异常来控制应用程序,则很难维护/调试。@mrmuggles我不同意,异常可能是构建代码的一种非常好的方法,例如,..g
对于插件中的插件;尝试processed_text=plugin.process(文本);除了例外情况1,做某事例外情况2;做点什么
没有比这更简单的替代方法,在这种情况下,这绝对是有道理的,您是在访问项目之前使用密钥,还是只是访问项目并捕获密钥错误?使用异常来构造工作流是一种反模式。这里有一个讨论:是的,您可以保存两行代码,但这并不是一个很好的维护解决方案。我会检查该项是否存在,事实上我可能会用一个方法来包装这段代码。@mrmuggles Python社区支持EAFP,也就是说请求原谅比请求允许更容易。这种风格在整个标准库和大型的必须使用Python的第三方库中得到广泛的支持。我在谷歌上随意搜索了一篇关于这个主题的博文:只有当Poll对象代表整个视图时,这才有效。如果你只是想查询一个页面中间的对象,你不想返回整个视图的404。只是想插手——我发现使用<代码>几乎总是更好的。得到而不是<代码>。我唯一一次使用
.first
是使用通用外键并进行验证,以确保最多只有一项。