ฉันจะนำเข้าข้อยกเว้น 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.

ไม่เกี่ยวข้องกับคำตอบของฉันด้านล่างนี้ get () โทรลบคำตอบที่เป็นปัญหาหรือไม่? ถ้าเป็นเช่นนั้นจริง ๆ แล้วควรเป็น DELETE ไม่ใช่ GET
Steve Jalim

คำตอบ:


136

คุณไม่จำเป็นต้องนำเข้า - เนื่องจากคุณได้เขียนอย่างถูกต้องแล้วDoesNotExistเป็นคุณสมบัติของแบบจำลองเองในกรณีAnswerนี้

ปัญหาของคุณคือการที่คุณจะเรียกgetวิธีการ - ซึ่งทำให้เกิดข้อยกเว้น - assertRaisesก่อนที่มันจะถูกส่งไปยัง คุณต้องแยกอาร์กิวเมนต์ออกจากสิ่งที่เรียกได้ตามที่อธิบายไว้ในเอกสารที่ไม่เหมาะสมที่สุด :

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 แต่ละรายการไม่ใช่ภายใน a ().
Martin B.

1
แน่นอน! ฉันรู้สึกเหมือนโดโรธีอยู่ที่นี่ ฉันค้นหาทั้งที่สูงและต่ำเพียงเพื่อจะพบว่ามันอยู่กับฉันตลอดมา!
Nick S

Python 3.6 / Django 2.2 เท่านั้นที่withแก้ปัญหาได้สำหรับฉัน
theruss

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ในกรณีนี้มันจะเป็น


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

สิ่งนี้ไม่ได้ตอบคำถามตามที่ร้องขออย่างแน่นอน แต่ก็ยังคงเป็นทางออกที่ดีโดยเสนอแนวทางที่แตกต่างออกไปเพื่อให้ได้ผลลัพธ์ที่ต้องการ
cezar

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.