Как импортировать исключение Django DoesNotExist?

122

Я пытаюсь создать UnitTest, чтобы убедиться, что объект был удален.

from django.utils import unittest
def test_z_Kallie_can_delete_discussion_response(self):
  ...snip...
  self._driver.get("http://localhost:8000/questions/3/want-a-discussion") 
  self.assertRaises(Answer.DoesNotExist, Answer.objects.get(body__exact = '<p>User can reply to discussion.</p>'))

Я получаю сообщение об ошибке:

DoesNotExist: Answer matching query does not exist.
BryanWheelock
источник
Это не связано с моим ответом ниже, это вызов get (), удаляющий ответ, о котором идет речь? Если да, то это действительно должно быть DELETE, а не GET.
Стив Джалим

Ответы:

136

Его не нужно импортировать - как вы уже правильно написали DoesNotExist, в данном случае это свойство самой модели Answer.

Ваша проблема в том, что вы вызываете getметод, который вызывает исключение, прежде чем он будет передан assertRaises. Вам необходимо отделить аргументы от вызываемого, как описано в документации unittest :

self.assertRaises(Answer.DoesNotExist, Answer.objects.get, body__exact='<p>User can reply to discussion.</p>')

или лучше:

with self.assertRaises(Answer.DoesNotExist):
    Answer.objects.get(body__exact='<p>User can reply to discussion.</p>')
Дэниел Розман
источник
1
Хороший ответ, только первый из приведенных выше фрагментов будет обнаружен как недопустимый синтаксис (по крайней мере, Python 2.7)., Должно быть self.assertRaises(Answer.DoesNotExist, Answer.objects.get, body__exact = '<p>User can reply to discussion.</p>')- то есть с getаргументами, добавленными как отдельные аргументы kw, а не внутри ().
Martin B.
1
Ох, конечно! Я чувствую себя здесь Дороти. Я искал повсюду и обнаружил, что он был со мной все время!
Nick S
Python 3.6 / Django 2.2 только withрешение сработало для меня.
Терусс
183

Вы также можете импортировать ObjectDoesNotExistиз django.core.exceptions, если хотите универсальный, независимый от модели способ перехвата исключения:

from django.core.exceptions import ObjectDoesNotExist

try:
    SomeModel.objects.get(pk=1)
except ObjectDoesNotExist:
    print 'Does Not Exist!'
Крис Прэтт
источник
10

DoesNotExistвсегда является несуществующим свойством модели. В этом случае было бы Answer.DoesNotExist.

defrex
источник
3

Следует обратить внимание на то, что второй параметр assertRaises должен быть вызываемым, а не просто свойством. Например, у меня возникли трудности с этим утверждением:

self.assertRaises(AP.DoesNotExist, self.fma.ap)

но это сработало нормально:

self.assertRaises(AP.DoesNotExist, lambda: self.fma.ap)
Сюн Чямиов
источник
3
self.assertFalse(Answer.objects.filter(body__exact='<p>User...discussion.</p>').exists())
Крис
источник
Это не совсем соответствует запросу. Но это по-прежнему хорошее решение, предлагающее другой подход для получения желаемого результата.
Цезарь
0

Вот как я делаю такой тест.

from foo.models import Answer

def test_z_Kallie_can_delete_discussion_response(self):

  ...snip...

  self._driver.get("http://localhost:8000/questions/3/want-a-discussion") 
  try:
      answer = Answer.objects.get(body__exact = '<p>User can reply to discussion.</p>'))      
      self.fail("Should not have reached here! Expected no Answer object. Found %s" % answer
  except Answer.DoesNotExist:
      pass # all is as expected
Стив Джалим
источник