mirror of https://github.com/django/django.git
Fixed #2756 -- Modified the get_object_or_404/get_list_or_404 shortcuts 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
This commit is contained in:
parent
c3f891210a
commit
e1c6e987d0
|
@ -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
|
||||
|
|
|
@ -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
|
||||
=======================
|
||||
|
||||
|
|
|
@ -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,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!>]
|
||||
|
||||
"""}
|
Loading…
Reference in New Issue