首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >可以从调用函数的位置访问的状态代码的替代方案是什么?异常?(Python,Django)

可以从调用函数的位置访问的状态代码的替代方案是什么?异常?(Python,Django)
EN

Stack Overflow用户
提问于 2017-08-30 03:10:11
回答 2查看 66关注 0票数 0

我想在一个函数中引发一个异常,然后在其他地方(在Django视图和我的单元测试中)检查它是否被引发。下面的代码使用了状态代码,并且可以正常工作。但我不知道如何在例外情况下做同样的事情--似乎每个人都同意,这是做这类事情的正确方式。

使用自定义错误消息对我来说很重要。不是打印它们,而是在代码中检测和使用它们(主要是用Django消息将它们转发给最终用户)。

如果utils.add_foo中出现异常,我不知道如何签入add_foo_view

在单元测试中,我尝试了像assertWarnsRegex(Warning, 'blah went wrong')这样的东西,但这并没有费心检查消息是否实际上是相同的。

views.py:

代码语言:javascript
复制
from django.contrib import messages

from .utils import add_foo


def add_foo_view(request):
    if request.method == 'POST':

        status = add_foo(request.POST['bar'])
        if not status == 'Bar was added.':
            messages.error(request, status)

        return render(request, 'index.html')
    else:
        return render(request, 'add_foo.html')

utils.py:

代码语言:javascript
复制
def add_foo(bar):

    if not spamifyable(bar):
        return 'Bar can not be spamified.'

    try:
        eggs = Egg.objects.get(baz=bar)
    except:
        return 'Bar has no eggs.'

    do_things(bar)

    return 'Bar was added.'

tests.py:

代码语言:javascript
复制
def test_bar_without_eggs(self):

    status = add_foo(eggless_bar)

    assertEqual(status, 'Bar has no eggs.')

我使用Python 3.5.2和Django 1.11.4。

编辑:我不确定在这里异常是否是正确的选择。我经常读到,例外只适用于意想不到的事情。但我在这里遇到的情况是用户输入的错误,这是非常意料之中的。所以我的问题并不是如何处理异常,而是如何正确地使用Python的方式,无论如何,我希望验证发生在单独的utils位置(普通的,没有Django),而不是在视图中。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-06-01 06:05:48

add_foo返回的明确的成功消息可能看起来更清楚,但可能不是一个好主意。该函数不需要返回任何内容。如果没有引发异常,则可以假定它是成功的。

我可以创建一个自定义异常并在__init__中添加message属性。这样,它就可以作为e.message进行访问,在我的例子中,它将被转发到views.py中的索引页。

utils.py

代码语言:javascript
复制
class AddFooException(Exception):

    def __init__(self, message):
        self.message = message


def add_foo(bar):

    if not spamifyable(bar):
        raise AddFooException('Bar can not be spamified.')

    try:
        eggs = Egg.objects.get(baz=bar)
    except:
        raise AddFooException('Bar has no eggs.')

    do_things(bar)

views.py

代码语言:javascript
复制
from django.contrib import messages

from .utils import add_foo, AddFooException


def add_foo_view(request):
    if request.method == 'POST':
        bar = request.POST['bar']

        try:
            add_foo(bar)
        except AddFooException as e:
            messages.error(request, e.message)


        return render(request, 'index.html')
    else:
        return render(request, 'add_foo.html')
票数 0
EN

Stack Overflow用户

发布于 2017-08-30 03:18:59

您可以使用' raise‘语句引发异常,如下所示:

代码语言:javascript
复制
raise Exception("Bar has no eggs.")

您还可以通过继承Exception内置类来创建自定义异常,如:

代码语言:javascript
复制
class MyException(Exception):
    pass

然后您可以执行以下操作:

代码语言:javascript
复制
raise MyException("Bar has no eggs.")

您可以使用try-except块捕获引发的异常:

代码语言:javascript
复制
try:
    function_that_raises_exception(args)
except MyException:
    function_to _handle_exception(args)

因此,在views.py中,您可以执行以下操作:

代码语言:javascript
复制
from django.contrib import messages

from .utils import add_foo, MyException


def add_foo_view(request):
    if request.method == 'POST':
        try:
            add_foo(request.POST['bar'])
        except MyException as e:
            messages.error(request, str(e))

        return render(request, 'index.html')
    else:
        return render(request, 'add_foo.html')
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45946686

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档