Jak zaimportować wyjątek Django DoesNotExist?

122

Próbuję utworzyć UnitTest, aby sprawdzić, czy obiekt został usunięty.

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>'))

Ciągle otrzymuję błąd:

DoesNotExist: Answer matching query does not exist.
BryanWheelock
źródło
Nie ma związku z moją odpowiedzią poniżej, czy to wywołanie get () usuwa daną odpowiedź? Jeśli tak, to naprawdę powinno to być DELETE, a nie GET.
Steve Jalim

Odpowiedzi:

136

Nie musisz go importować - jak już poprawnie napisałeś, DoesNotExistjest to w tym przypadku własność samego modelu Answer.

Twoim problemem jest to, że wywołujesz getmetodę - która zgłasza wyjątek - zanim zostanie przekazana do assertRaises. Musisz oddzielić argumenty od wywoływanych, jak opisano w niezatwierdzonej dokumentacji :

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

albo lepiej:

with self.assertRaises(Answer.DoesNotExist):
    Answer.objects.get(body__exact='<p>User can reply to discussion.</p>')
Daniel Roseman
źródło
1
Dobra odpowiedź, tylko pierwszy z powyższych fragmentów zostanie przechwycony jako niepoprawna składnia (przynajmniej przez Python 2.7)., Powinien być self.assertRaises(Answer.DoesNotExist, Answer.objects.get, body__exact = '<p>User can reply to discussion.</p>')- tj. Z getargumentami dodanymi jako poszczególne argumenty kw, a nie wewnątrz a ().
Martin B.
1
Augh, oczywiście! Czuję się tu jak Dorothy. Szukałem wysoko i nisko, ale okazało się, że cały czas był ze mną!
Nick S
Python 3.6 / Django 2.2 tylko withrozwiązanie działało u mnie.
theruss
183

Możesz także importować ObjectDoesNotExistz django.core.exceptions, jeśli chcesz uzyskać ogólny, niezależny od modelu sposób przechwytywania wyjątku:

from django.core.exceptions import ObjectDoesNotExist

try:
    SomeModel.objects.get(pk=1)
except ObjectDoesNotExist:
    print 'Does Not Exist!'
Chris Pratt
źródło
10

DoesNotExistjest zawsze własnością modelu, który nie istnieje. W tym przypadku tak by było Answer.DoesNotExist.

defrex
źródło
3

Należy zwrócić uwagę na to, że drugi parametr assertRaises musi być wywoływalny - a nie tylko właściwość. Na przykład miałem trudności z tym stwierdzeniem:

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

ale to działało dobrze:

self.assertRaises(AP.DoesNotExist, lambda: self.fma.ap)
Xiong Chiamiov
źródło
3
self.assertFalse(Answer.objects.filter(body__exact='<p>User...discussion.</p>').exists())
Chris
źródło
To nie jest dokładną odpowiedzią na pytanie. Ale to wciąż fajne rozwiązanie, oferujące inne podejście do uzyskania pożądanego rezultatu.
cezar
0

Tak robię taki test.

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
Steve Jalim
źródło