Làm cách nào để nhập ngoại lệ Django DoesNotExist?


122

Tôi đang cố tạo UnitTest để xác minh rằng một đối tượng đã bị xóa.

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

Tôi tiếp tục nhận được lỗi:

DoesNotExist: Answer matching query does not exist.

Không liên quan đến câu trả lời của tôi bên dưới, lệnh get () đó có xóa Câu trả lời được đề cập không? Nếu vậy, điều đó thực sự phải là XÓA, không phải NHẬN.
Steve Jalim

Câu trả lời:


136

Bạn không cần nhập nó - như bạn đã viết chính xác, DoesNotExistlà một thuộc tính của chính mô hình, trong trường hợp này Answer.

Vấn đề của bạn là bạn đang gọi getphương thức - làm tăng ngoại lệ - trước khi nó được chuyển đến assertRaises. Bạn cần tách các đối số khỏi có thể gọi, như được mô tả trong tài liệu mới nhất :

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

hoặc tốt hơn:

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

1
Câu trả lời hay, chỉ đoạn mã đầu tiên trong số các đoạn mã ở trên sẽ bị bắt là cú pháp không hợp lệ (ít nhất là bằng Python 2.7)., Nên self.assertRaises(Answer.DoesNotExist, Answer.objects.get, body__exact = '<p>User can reply to discussion.</p>')- tức là với getcác đối số của được thêm vào dưới dạng các kw args riêng lẻ, không phải bên trong a ().
Martin B.

1
Tất nhiên! Tôi cảm thấy giống như Dorothy ở đây. Tôi đã tìm kiếm cao và thấp, chỉ để tìm thấy nó đã ở bên tôi suốt!
Nick S

Python 3.6 / Django 2.2 chỉ có withgiải pháp phù hợp với tôi.
theruss

183

Bạn cũng có thể nhập ObjectDoesNotExisttừ django.core.exceptions, nếu bạn muốn một cách chung, không phụ thuộc vào mô hình để bắt ngoại lệ:

from django.core.exceptions import ObjectDoesNotExist

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

10

DoesNotExistluôn luôn là một thuộc tính của mô hình không tồn tại. Trong trường hợp này, nó sẽ là Answer.DoesNotExist.


3

Một điều cần chú ý là tham số thứ hai assertRaises cần phải là một thuộc tính có thể gọi được - không chỉ là một thuộc tính. Ví dụ, tôi gặp khó khăn với câu lệnh này:

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

nhưng điều này hoạt động tốt:

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

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

Điều này không trả lời chính xác câu hỏi như được yêu cầu. Nhưng nó vẫn là một giải pháp tốt, cung cấp một cách tiếp cận khác để có được kết quả mong muốn.
cezar

0

Đây là cách tôi làm một bài kiểm tra như vậy.

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.