Wie importiere ich die Django DoesNotExist-Ausnahme?

122

Ich versuche, einen UnitTest zu erstellen, um zu überprüfen, ob ein Objekt gelöscht wurde.

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

Ich bekomme immer wieder den Fehler:

DoesNotExist: Answer matching query does not exist.
BryanWheelock
quelle
Ist dieser get () -Aufruf unabhängig von meiner Antwort unten und löscht die betreffende Antwort? Wenn ja, sollte das wirklich wirklich ein DELETE sein, kein GET.
Steve Jalim

Antworten:

136

Sie müssen es nicht importieren - wie Sie bereits richtig geschrieben haben, DoesNotExistist es in diesem Fall eine Eigenschaft des Modells selbst Answer.

Ihr Problem ist, dass Sie die getMethode aufrufen , wodurch die Ausnahme ausgelöst wird, bevor sie an übergeben wird assertRaises. Sie müssen die Argumente vom aufrufbaren trennen, wie in der unittest-Dokumentation beschrieben :

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

oder besser:

with self.assertRaises(Answer.DoesNotExist):
    Answer.objects.get(body__exact='<p>User can reply to discussion.</p>')
Daniel Roseman
quelle
1
Gute Antwort, nur das erste der oben genannten Snippets wird als ungültige Syntax abgefangen (zumindest von Python 2.7). Sollte self.assertRaises(Answer.DoesNotExist, Answer.objects.get, body__exact = '<p>User can reply to discussion.</p>')- dh mit get's Argumenten als einzelne kw-Argumente hinzugefügt werden, nicht innerhalb von a ().
Martin B.
1
Augh natürlich! Ich fühle mich wie Dorothy hier. Ich suchte hoch und niedrig, nur um herauszufinden, dass es die ganze Zeit bei mir war!
Nick S
Python 3.6 / Django 2.2 Nur die withLösung hat bei mir funktioniert.
Theruss
182

Sie können auch importieren ObjectDoesNotExistaus django.core.exceptions, wenn Sie möchten , eine generische, modellunabhängige Möglichkeit , die Ausnahme zu fangen:

from django.core.exceptions import ObjectDoesNotExist

try:
    SomeModel.objects.get(pk=1)
except ObjectDoesNotExist:
    print 'Does Not Exist!'
Chris Pratt
quelle
10

DoesNotExistist immer eine Eigenschaft des Modells, die nicht existiert. In diesem Fall wäre es Answer.DoesNotExist.

defrex
quelle
3

Eine Sache, auf die Sie achten müssen, ist, dass der zweite Parameter ein aufrufbarer Parameter sein assertRaises muss - nicht nur eine Eigenschaft. Zum Beispiel hatte ich Schwierigkeiten mit dieser Aussage:

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

aber das hat gut funktioniert:

self.assertRaises(AP.DoesNotExist, lambda: self.fma.ap)
Xiong Chiamiov
quelle
3
self.assertFalse(Answer.objects.filter(body__exact='<p>User...discussion.</p>').exists())
Chris
quelle
Dies beantwortet die angeforderte Frage nicht genau. Aber es ist immer noch eine gute Lösung, die einen anderen Ansatz bietet, um das gewünschte Ergebnis zu erzielen.
Cezar
0

So mache ich einen solchen 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
quelle