我想在一个函数中引发一个异常,然后在其他地方(在Django视图和我的单元测试中)检查它是否被引发。下面的代码使用了状态代码,并且可以正常工作。但我不知道如何在例外情况下做同样的事情--似乎每个人都同意,这是做这类事情的正确方式。
使用自定义错误消息对我来说很重要。不是打印它们,而是在代码中检测和使用它们(主要是用Django消息将它们转发给最终用户)。
如果utils.add_foo
中出现异常,我不知道如何签入add_foo_view
。
在单元测试中,我尝试了像assertWarnsRegex
(Warning, 'blah went wrong')
这样的东西,但这并没有费心检查消息是否实际上是相同的。
views.py:
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:
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:
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),而不是在视图中。
发布于 2018-06-01 06:05:48
由add_foo
返回的明确的成功消息可能看起来更清楚,但可能不是一个好主意。该函数不需要返回任何内容。如果没有引发异常,则可以假定它是成功的。
我可以创建一个自定义异常并在__init__
中添加message
属性。这样,它就可以作为e.message
进行访问,在我的例子中,它将被转发到views.py
中的索引页。
utils.py
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
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')
发布于 2017-08-30 03:18:59
您可以使用' raise‘语句引发异常,如下所示:
raise Exception("Bar has no eggs.")
您还可以通过继承Exception内置类来创建自定义异常,如:
class MyException(Exception):
pass
然后您可以执行以下操作:
raise MyException("Bar has no eggs.")
您可以使用try-except块捕获引发的异常:
try:
function_that_raises_exception(args)
except MyException:
function_to _handle_exception(args)
因此,在views.py中,您可以执行以下操作:
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')
https://stackoverflow.com/questions/45946686
复制相似问题