Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fixed #2756 -- Modified the get_object_or_404/get_list_or_404 shortcu…

…ts to accept model managers as well as model classes. Thanks, Gary Wilson.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@4275 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit e1c6e987d07efb3ee9471e63541f9561b461ea44 1 parent c3f8912
Russell Keith-Magee freakboy3742 authored
15 django/shortcuts/__init__.py
View
@@ -4,20 +4,29 @@
from django.template import loader
from django.http import HttpResponse, Http404
-
+from django.db.models.manager import Manager
def render_to_response(*args, **kwargs):
return HttpResponse(loader.render_to_string(*args, **kwargs))
load_and_render = render_to_response # For backwards compatibility.
def get_object_or_404(klass, *args, **kwargs):
+ if isinstance(klass, Manager):
+ manager = klass
+ klass = manager.model
+ else:
+ manager = klass._default_manager
try:
- return klass._default_manager.get(*args, **kwargs)
+ return manager.get(*args, **kwargs)
except klass.DoesNotExist:
raise Http404
def get_list_or_404(klass, *args, **kwargs):
- obj_list = list(klass._default_manager.filter(*args, **kwargs))
+ if isinstance(klass, Manager):
+ manager = klass
+ else:
+ manager = klass._default_manager
+ obj_list = list(manager.filter(*args, **kwargs))
if not obj_list:
raise Http404
return obj_list
40 docs/db-api.txt
View
@@ -1704,6 +1704,46 @@ For every ``ImageField``, the object will have ``get_FOO_height()`` and
``get_FOO_width()`` methods, where ``FOO`` is the name of the field. This
returns the height (or width) of the image, as an integer, in pixels.
+Shortcuts
+=========
+
+As you develop views, you will discover a number of common idioms in the
+way you use the database API. Django encodes some of these idioms as
+shortcuts that can be used to simplify the process of writing views.
+
+get_object_or_404()
+-------------------
+
+One common idiom to use ``get()`` and raise ``Http404`` if the
+object doesn't exist. This idiom is captured by ``get_object_or_404()``.
+This function takes a Django model as its first argument and an
+arbitrary number of keyword arguments, which it passes to the manager's
+``get()`` function. It raises ``Http404`` if the object doesn't
+exist. For example::
+
+ # Get the Entry with a primary key of 3
+ e = get_object_or_404(Entry, pk=3)
+
+When you provide a model to this shortcut function, the default manager
+is used to execute the underlying ``get()`` query. If you don't want to
+use the default manager, or you want to search a list of related objects,
+you can provide ``get_object_or_404()`` with a manager object, instead.
+For example::
+
+ # Get the author of blog instance `e` with a name of 'Fred'
+ a = get_object_or_404(e.authors, name='Fred')
+
+ # Use a custom manager 'recent_entries' in the search for an
+ # entry with a primary key of 3
+ e = get_object_or_404(Entry.recent_entries, pk=3)
+
+get_list_or_404()
+-----------------
+
+``get_list_or_404`` behaves the same was as ``get_object_or_404()``
+-- except the it uses using ``filter()`` instead of ``get()``. It raises
+``Http404`` if the list is empty.
+
Falling back to raw SQL
=======================
2  docs/tutorial03.txt
View
@@ -300,7 +300,7 @@ rewritten::
The ``get_object_or_404()`` function takes a Django model module as its first
argument and an arbitrary number of keyword arguments, which it passes to the
-module's ``get_object()`` function. It raises ``Http404`` if the object doesn't
+module's ``get()`` function. It raises ``Http404`` if the object doesn't
exist.
.. admonition:: Philosophy
0  tests/modeltests/get_object_or_404/__init__.py
View
No changes.
86 tests/modeltests/get_object_or_404/models.py
View
@@ -0,0 +1,86 @@
+"""
+34. DB-API Shortcuts
+
+get_object_or_404 is a shortcut function to be used in view functions for
+performing a get() lookup and raising a Http404 exception if a DoesNotExist
+exception was rasied during the get() call.
+
+get_list_or_404 is a shortcut function to be used in view functions for
+performing a filter() lookup and raising a Http404 exception if a DoesNotExist
+exception was rasied during the filter() call.
+"""
+
+from django.db import models
+from django.http import Http404
+from django.shortcuts import get_object_or_404, get_list_or_404
+
+class Author(models.Model):
+ name = models.CharField(maxlength=50)
+
+ def __str__(self):
+ return self.name
+
+class ArticleManager(models.Manager):
+ def get_query_set(self):
+ return super(ArticleManager, self).get_query_set().filter(authors__name__icontains='sir')
+
+class Article(models.Model):
+ authors = models.ManyToManyField(Author)
+ title = models.CharField(maxlength=50)
+ objects = models.Manager()
+ by_a_sir = ArticleManager()
+
+ def __str__(self):
+ return self.title
+
+__test__ = {'API_TESTS':"""
+# Create some Authors.
+>>> a = Author.objects.create(name="Brave Sir Robin")
+>>> a.save()
+>>> a2 = Author.objects.create(name="Patsy")
+>>> a2.save()
+
+# No Articles yet, so we should get a Http404 error.
+>>> get_object_or_404(Article, title="Foo")
+Traceback (most recent call last):
+...
+Http404
+
+# Create an Article.
+>>> article = Article.objects.create(title="Run away!")
+>>> article.authors = [a, a2]
+>>> article.save()
+
+# get_object_or_404 can be passed a Model to query.
+>>> get_object_or_404(Article, title__contains="Run")
+<Article: Run away!>
+
+# We can also use the the Article manager through an Author object.
+>>> get_object_or_404(a.article_set, title__contains="Run")
+<Article: Run away!>
+
+# No articles containing "Camelot". This should raise a Http404 error.
+>>> get_object_or_404(a.article_set, title__contains="Camelot")
+Traceback (most recent call last):
+...
+Http404
+
+# Custom managers can be used too.
+>>> get_object_or_404(Article.by_a_sir, title="Run away!")
+<Article: Run away!>
+
+# get_list_or_404 can be used to get lists of objects
+>>> get_list_or_404(a.article_set, title__icontains='Run')
+[<Article: Run away!>]
+
+# Http404 is returned if the list is empty
+>>> get_list_or_404(a.article_set, title__icontains='Shrubbery')
+Traceback (most recent call last):
+...
+Http404
+
+# Custom managers can be used too.
+>>> get_list_or_404(Article.by_a_sir, title__icontains="Run")
+[<Article: Run away!>]
+
+"""}
Please sign in to comment.
Something went wrong with that request. Please try again.