Django DoesNotExist istisnasını nasıl içe aktarırım?


122

Bir nesnenin silindiğini doğrulamak için bir UnitTest oluşturmaya çalışıyorum.

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

Şu hatayı alıyorum:

DoesNotExist: Answer matching query does not exist.

Aşağıdaki cevabımla ilgisi olmayan, bu get () çağrısının söz konusu Yanıtı silmesi mi? Eğer öyleyse, bu gerçekten bir GET değil, bir DELETE olmalıdır.
Steve Jalim

Yanıtlar:


136

İçeri aktarmanıza gerek yoktur - zaten doğru bir şekilde yazdığınız gibi, DoesNotExistbu durumda modelin kendisinin bir özelliğidir Answer.

Probleminiz, getistisnayı ortaya çıkaran yöntemi, geçilmeden önce çağırmanızdır assertRaises. Unittest belgelerinde açıklandığı gibi argümanları çağrılabilirden ayırmanız gerekir :

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

ya da daha iyisi:

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

1
. İyi cevap sadece yukarıda snippet'lerin ilk geçersiz sözdizimi olarak yakalanacak (Python 2.7 ile en az) olmalıdır self.assertRaises(Answer.DoesNotExist, Answer.objects.get, body__exact = '<p>User can reply to discussion.</p>')- yani ile getbireysel kw args olarak eklenmiştir savunmasından değil, bir iç ().
Martin B.

1
Ah, tabii ki! Burada Dorothy gibi hissediyorum. Yüksek ve alçak bir arayış içindeydim, sadece başından beri benimle olduğunu bulmak için!
Nick S

Python 3.6 / Django 2.2 sadece withçözüm benim için çalıştı.
theruss

183

İstisnayı yakalamak için genel, modelden bağımsız bir yol istiyorsanız, ObjectDoesNotExistşuradan da içe aktarabilirsiniz django.core.exceptions:

from django.core.exceptions import ObjectDoesNotExist

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

10

DoesNotExisther zaman modelin var olmayan bir özelliğidir. Bu durumda olur Answer.DoesNotExist.


3

Dikkat edilmesi gereken bir şey için ikinci parametre olmasıdır assertRaises ihtiyaçları sadece bir özelliği - bir çağrılabilir olması. Örneğin, şu ifadeyle ilgili zorluklar yaşadım:

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

ama bu iyi çalıştı:

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

3
self.assertFalse(Answer.objects.filter(body__exact='<p>User...discussion.</p>').exists())

Bu, soruyu istendiği gibi yanıtlamaz. Ancak yine de güzel bir çözüm, istenen sonucu elde etmek için farklı bir yaklaşım sunuyor.
Cezar

0

Ben böyle bir test yapıyorum.

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.