tests.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. from django.db.models import Q
  2. from django.http import Http404
  3. from django.shortcuts import get_list_or_404, get_object_or_404
  4. from django.test import TestCase
  5. from .models import Article, Author
  6. class GetObjectOr404Tests(TestCase):
  7. def test_get_object_or_404(self):
  8. a1 = Author.objects.create(name="Brave Sir Robin")
  9. a2 = Author.objects.create(name="Patsy")
  10. # No Articles yet, so we should get an Http404 error.
  11. with self.assertRaises(Http404):
  12. get_object_or_404(Article, title="Foo")
  13. article = Article.objects.create(title="Run away!")
  14. article.authors.set([a1, a2])
  15. # get_object_or_404 can be passed a Model to query.
  16. self.assertEqual(
  17. get_object_or_404(Article, title__contains="Run"),
  18. article
  19. )
  20. # We can also use the Article manager through an Author object.
  21. self.assertEqual(
  22. get_object_or_404(a1.article_set, title__contains="Run"),
  23. article
  24. )
  25. # No articles containing "Camelot". This should raise an Http404 error.
  26. with self.assertRaises(Http404):
  27. get_object_or_404(a1.article_set, title__contains="Camelot")
  28. # Custom managers can be used too.
  29. self.assertEqual(
  30. get_object_or_404(Article.by_a_sir, title="Run away!"),
  31. article
  32. )
  33. # QuerySets can be used too.
  34. self.assertEqual(
  35. get_object_or_404(Article.objects.all(), title__contains="Run"),
  36. article
  37. )
  38. # Just as when using a get() lookup, you will get an error if more than
  39. # one object is returned.
  40. with self.assertRaises(Author.MultipleObjectsReturned):
  41. get_object_or_404(Author.objects.all())
  42. # Using an empty QuerySet raises an Http404 error.
  43. with self.assertRaises(Http404):
  44. get_object_or_404(Article.objects.none(), title__contains="Run")
  45. # get_list_or_404 can be used to get lists of objects
  46. self.assertEqual(
  47. get_list_or_404(a1.article_set, title__icontains="Run"),
  48. [article]
  49. )
  50. # Http404 is returned if the list is empty.
  51. with self.assertRaises(Http404):
  52. get_list_or_404(a1.article_set, title__icontains="Shrubbery")
  53. # Custom managers can be used too.
  54. self.assertEqual(
  55. get_list_or_404(Article.by_a_sir, title__icontains="Run"),
  56. [article]
  57. )
  58. # QuerySets can be used too.
  59. self.assertEqual(
  60. get_list_or_404(Article.objects.all(), title__icontains="Run"),
  61. [article]
  62. )
  63. # Q objects.
  64. self.assertEqual(
  65. get_object_or_404(
  66. Article,
  67. Q(title__startswith='Run') | Q(title__startswith='Walk'),
  68. authors__name__contains='Brave',
  69. ),
  70. article,
  71. )
  72. self.assertEqual(
  73. get_list_or_404(
  74. Article,
  75. Q(title__startswith='Run') | Q(title__startswith='Walk'),
  76. authors__name='Patsy',
  77. ),
  78. [article],
  79. )
  80. def test_bad_class(self):
  81. # Given an argument klass that is not a Model, Manager, or Queryset
  82. # raises a helpful ValueError message
  83. msg = "First argument to get_object_or_404() must be a Model, Manager, or QuerySet, not 'str'."
  84. with self.assertRaisesMessage(ValueError, msg):
  85. get_object_or_404("Article", title__icontains="Run")
  86. class CustomClass:
  87. pass
  88. msg = "First argument to get_object_or_404() must be a Model, Manager, or QuerySet, not 'CustomClass'."
  89. with self.assertRaisesMessage(ValueError, msg):
  90. get_object_or_404(CustomClass, title__icontains="Run")
  91. # Works for lists too
  92. msg = "First argument to get_list_or_404() must be a Model, Manager, or QuerySet, not 'list'."
  93. with self.assertRaisesMessage(ValueError, msg):
  94. get_list_or_404([Article], title__icontains="Run")
  95. def test_get_object_or_404_queryset_attribute_error(self):
  96. """AttributeError raised by QuerySet.get() isn't hidden."""
  97. with self.assertRaisesMessage(AttributeError, 'AttributeErrorManager'):
  98. get_object_or_404(Article.attribute_error_objects, id=42)
  99. def test_get_list_or_404_queryset_attribute_error(self):
  100. """AttributeError raised by QuerySet.filter() isn't hidden."""
  101. with self.assertRaisesMessage(AttributeError, 'AttributeErrorManager'):
  102. get_list_or_404(Article.attribute_error_objects, title__icontains='Run')