Fixed #4373 -- Modified the get_object_or_404/get_list_or_404 shortcuts to also accept `QuerySet`s. Thanks SuperJared.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5746 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
63cc023eea
commit
cae92ae615
1
AUTHORS
1
AUTHORS
|
@ -242,6 +242,7 @@ answer newbie questions, and generally made Django that much better:
|
|||
Thomas Steinacher <http://www.eggdrop.ch/>
|
||||
nowell strite
|
||||
Sundance
|
||||
SuperJared
|
||||
Radek Švarz <http://www.svarz.cz/translate/>
|
||||
Swaroop C H <http://www.swaroopch.info>
|
||||
Aaron Swartz <http://www.aaronsw.com/>
|
||||
|
|
|
@ -7,6 +7,7 @@ for convenience's sake.
|
|||
from django.template import loader
|
||||
from django.http import HttpResponse, Http404
|
||||
from django.db.models.manager import Manager
|
||||
from django.db.models.query import QuerySet
|
||||
|
||||
def render_to_response(*args, **kwargs):
|
||||
"""
|
||||
|
@ -16,40 +17,46 @@ 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_queryset(klass):
|
||||
"""
|
||||
Return a QuerySet from a Model, Manager, or QuerySet. Created to make
|
||||
get_object_or_404 and get_list_or_404 more DRY.
|
||||
"""
|
||||
if isinstance(klass, QuerySet):
|
||||
return klass
|
||||
elif isinstance(klass, Manager):
|
||||
manager = klass
|
||||
else:
|
||||
manager = klass._default_manager
|
||||
return manager.all()
|
||||
|
||||
def get_object_or_404(klass, *args, **kwargs):
|
||||
"""
|
||||
Use get() to return an object, or raise a Http404 exception if the object
|
||||
does not exist.
|
||||
|
||||
klass may be a Model or Manager object. All other passed
|
||||
klass may be a Model, Manager, or QuerySet object. All other passed
|
||||
arguments and keyword arguments are used in the get() query.
|
||||
|
||||
Note: Like with get(), an AssertionError will be raised if more than one
|
||||
object is found.
|
||||
"""
|
||||
if isinstance(klass, Manager):
|
||||
manager = klass
|
||||
klass = manager.model
|
||||
else:
|
||||
manager = klass._default_manager
|
||||
queryset = _get_queryset(klass)
|
||||
try:
|
||||
return manager.get(*args, **kwargs)
|
||||
except klass.DoesNotExist:
|
||||
raise Http404('No %s matches the given query.' % klass._meta.object_name)
|
||||
return queryset.get(*args, **kwargs)
|
||||
except queryset.model.DoesNotExist:
|
||||
raise Http404('No %s matches the given query.' % queryset.model._meta.object_name)
|
||||
|
||||
def get_list_or_404(klass, *args, **kwargs):
|
||||
"""
|
||||
Use filter() to return a list of objects, or raise a Http404 exception if
|
||||
the list is empty.
|
||||
the list is emtpy.
|
||||
|
||||
klass may be a Model or Manager object. All other passed
|
||||
klass may be a Model, Manager, or QuerySet object. All other passed
|
||||
arguments and keyword arguments are used in the filter() query.
|
||||
"""
|
||||
if isinstance(klass, Manager):
|
||||
manager = klass
|
||||
else:
|
||||
manager = klass._default_manager
|
||||
obj_list = list(manager.filter(*args, **kwargs))
|
||||
queryset = _get_queryset(klass)
|
||||
obj_list = list(queryset.filter(*args, **kwargs))
|
||||
if not obj_list:
|
||||
raise Http404('No %s matches the given query.' % manager.model._meta.object_name)
|
||||
raise Http404('No %s matches the given query.' % queryset.model._meta.object_name)
|
||||
return obj_list
|
||||
|
|
|
@ -1891,8 +1891,8 @@ 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
|
||||
arbitrary number of keyword arguments, which it passes to the default
|
||||
manager's ``get()`` function. It raises ``Http404`` if the object doesn't
|
||||
exist. For example::
|
||||
|
||||
# Get the Entry with a primary key of 3
|
||||
|
@ -1901,7 +1901,7 @@ exist. For example::
|
|||
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 if you want to search a list of related objects,
|
||||
you can provide ``get_object_or_404()`` with a manager object instead.
|
||||
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'
|
||||
|
@ -1911,6 +1911,14 @@ For example::
|
|||
# entry with a primary key of 3
|
||||
e = get_object_or_404(Entry.recent_entries, pk=3)
|
||||
|
||||
If you need to use a custom method that you added to a custom manager,
|
||||
then you can provide ``get_object_or_404()`` with a ``QuerySet`` object.
|
||||
For example::
|
||||
|
||||
# Use a QuerySet returned from a 'published' method of a custom manager
|
||||
# in the search for an entry with primary key of 5
|
||||
e = get_object_or_404(Entry.objects.published(), pk=5)
|
||||
|
||||
get_list_or_404()
|
||||
-----------------
|
||||
|
||||
|
|
|
@ -3,11 +3,11 @@
|
|||
|
||||
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.
|
||||
exception was raised 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.
|
||||
exception was raised during the filter() call.
|
||||
"""
|
||||
|
||||
from django.db import models
|
||||
|
@ -69,11 +69,28 @@ Http404: No Article matches the given query.
|
|||
>>> get_object_or_404(Article.by_a_sir, title="Run away!")
|
||||
<Article: Run away!>
|
||||
|
||||
# QuerySets can be used too.
|
||||
>>> get_object_or_404(Article.objects.all(), title__contains="Run")
|
||||
<Article: Run away!>
|
||||
|
||||
# Just as when using a get() lookup, you will get an error if more than one
|
||||
# object is returned.
|
||||
>>> get_object_or_404(Author.objects.all())
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
AssertionError: get() returned more than one Author -- it returned ...! Lookup parameters were {}
|
||||
|
||||
# Using an EmptyQuerySet raises a Http404 error.
|
||||
>>> get_object_or_404(Article.objects.none(), title__contains="Run")
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
Http404: No Article matches the given query.
|
||||
|
||||
# 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
|
||||
# Http404 is returned if the list is empty.
|
||||
>>> get_list_or_404(a.article_set, title__icontains='Shrubbery')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
|
@ -83,4 +100,8 @@ Http404: No Article matches the given query.
|
|||
>>> get_list_or_404(Article.by_a_sir, title__icontains="Run")
|
||||
[<Article: Run away!>]
|
||||
|
||||
# QuerySets can be used too.
|
||||
>>> get_list_or_404(Article.objects.all(), title__icontains="Run")
|
||||
[<Article: Run away!>]
|
||||
|
||||
"""}
|
||||
|
|
Loading…
Reference in New Issue