no articles yet so we should get an http404 error getobjector404 can be passed a model to query we can also use the article manager through an object no articles containing camelot this should raise an http404 error custom managers can be used too querysets can be used too just as when using a get lookup you will get an error if more than one object is returned using an empty queryset raises an http404 error getlistor404 can be used to get lists of objects http404 is returned if the list is empty custom managers can be used too querysets can be used too q objects given an argument klass that is not a model manager or queryset raises a helpful valueerror message works for lists too attributeerror raised by queryset get isn t hidden with self assertraisesmessageattributeerror attributeerrormanager getobjector404article attributeerrorobjects id42 def testgetlistor404querysetattributeerrorself no articles yet so we should get an http404 error get_object_or_404 can be passed a model to query we can also use the article manager through an object no articles containing camelot this should raise an http404 error custom managers can be used too querysets can be used too just as when using a get lookup you will get an error if more than one object is returned using an empty queryset raises an http404 error get_list_or_404 can be used to get lists of objects http404 is returned if the list is empty custom managers can be used too querysets can be used too q objects given an argument klass that is not a model manager or queryset raises a helpful valueerror message works for lists too attributeerror raised by queryset get isn t hidden attributeerror raised by queryset filter isn t hidden
from django.db.models import Q
from django.http import Http404
from django.shortcuts import get_list_or_404, get_object_or_404
from django.test import TestCase

from .models import Article, Author


class GetObjectOr404Tests(TestCase):
    def test_get_object_or_404(self):
        a1 = Author.objects.create(name="Brave Sir Robin")
        a2 = Author.objects.create(name="Patsy")

        
        with self.assertRaises(Http404):
            get_object_or_404(Article, title="Foo")

        article = Article.objects.create(title="Run away!")
        article.authors.set([a1, a2])
        
        self.assertEqual(get_object_or_404(Article, title__contains="Run"), article)

        
        self.assertEqual(
            get_object_or_404(a1.article_set, title__contains="Run"), article
        )

        
        with self.assertRaises(Http404):
            get_object_or_404(a1.article_set, title__contains="Camelot")

        
        self.assertEqual(
            get_object_or_404(Article.by_a_sir, title="Run away!"), article
        )

        
        self.assertEqual(
            get_object_or_404(Article.objects.all(), title__contains="Run"), article
        )

        
        

        with self.assertRaises(Author.MultipleObjectsReturned):
            get_object_or_404(Author.objects.all())

        
        with self.assertRaises(Http404):
            get_object_or_404(Article.objects.none(), title__contains="Run")

        
        self.assertEqual(
            get_list_or_404(a1.article_set, title__icontains="Run"), [article]
        )

        
        with self.assertRaises(Http404):
            get_list_or_404(a1.article_set, title__icontains="Shrubbery")

        
        self.assertEqual(
            get_list_or_404(Article.by_a_sir, title__icontains="Run"), [article]
        )

        
        self.assertEqual(
            get_list_or_404(Article.objects.all(), title__icontains="Run"), [article]
        )
        
        self.assertEqual(
            get_object_or_404(
                Article,
                Q(title__startswith="Run") | Q(title__startswith="Walk"),
                authors__name__contains="Brave",
            ),
            article,
        )
        self.assertEqual(
            get_list_or_404(
                Article,
                Q(title__startswith="Run") | Q(title__startswith="Walk"),
                authors__name="Patsy",
            ),
            [article],
        )

    def test_bad_class(self):
        
        
        msg = (
            "First argument to get_object_or_404() must be a Model, Manager, or "
            "QuerySet, not 'str'."
        )
        with self.assertRaisesMessage(ValueError, msg):
            get_object_or_404("Article", title__icontains="Run")

        class CustomClass:
            pass

        msg = (
            "First argument to get_object_or_404() must be a Model, Manager, or "
            "QuerySet, not 'CustomClass'."
        )
        with self.assertRaisesMessage(ValueError, msg):
            get_object_or_404(CustomClass, title__icontains="Run")

        
        msg = (
            "First argument to get_list_or_404() must be a Model, Manager, or "
            "QuerySet, not 'list'."
        )
        with self.assertRaisesMessage(ValueError, msg):
            get_list_or_404([Article], title__icontains="Run")

    def test_get_object_or_404_queryset_attribute_error(self):
        
        with self.assertRaisesMessage(AttributeError, "AttributeErrorManager"):
            get_object_or_404(Article.attribute_error_objects, id=42)

    def test_get_list_or_404_queryset_attribute_error(self):
        
        with self.assertRaisesMessage(AttributeError, "AttributeErrorManager"):
            get_list_or_404(Article.attribute_error_objects, title__icontains="Run")