Django

Code

Changeset 5746

Show
Ignore:
Timestamp:
07/21/07 22:41:11 (10 months ago)
Author:
gwilson
Message:

Fixed #4373 -- Modified the get_object_or_404/get_list_or_404 shortcuts to also accept QuerySets. Thanks SuperJared?.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/AUTHORS

    r5738 r5746  
    243243    nowell strite 
    244244    Sundance 
     245    SuperJared 
    245246    Radek Å varz <http://www.svarz.cz/translate/> 
    246247    Swaroop C H <http://www.swaroopch.info> 
  • django/trunk/django/shortcuts/__init__.py

    r5745 r5746  
    88from django.http import HttpResponse, Http404 
    99from django.db.models.manager import Manager 
     10from django.db.models.query import QuerySet 
    1011 
    1112def render_to_response(*args, **kwargs): 
     
    1718load_and_render = render_to_response # For backwards compatibility. 
    1819 
     20def _get_queryset(klass): 
     21    """ 
     22    Return a QuerySet from a Model, Manager, or QuerySet. Created to make 
     23    get_object_or_404 and get_list_or_404 more DRY. 
     24    """ 
     25    if isinstance(klass, QuerySet): 
     26        return klass 
     27    elif isinstance(klass, Manager): 
     28        manager = klass 
     29    else: 
     30        manager = klass._default_manager 
     31    return manager.all() 
     32 
    1933def get_object_or_404(klass, *args, **kwargs): 
    2034    """ 
     
    2236    does not exist. 
    2337 
    24     klass may be a Model or Manager object.  All other passed 
     38    klass may be a Model, Manager, or QuerySet object.  All other passed 
    2539    arguments and keyword arguments are used in the get() query. 
    2640 
     
    2842    object is found. 
    2943    """ 
    30     if isinstance(klass, Manager): 
    31         manager = klass 
    32         klass = manager.model 
    33     else: 
    34         manager = klass._default_manager 
     44    queryset = _get_queryset(klass) 
    3545    try: 
    36         return manager.get(*args, **kwargs) 
    37     except klass.DoesNotExist: 
    38         raise Http404('No %s matches the given query.' % klass._meta.object_name) 
     46        return queryset.get(*args, **kwargs) 
     47    except queryset.model.DoesNotExist: 
     48        raise Http404('No %s matches the given query.' % queryset.model._meta.object_name) 
    3949 
    4050def get_list_or_404(klass, *args, **kwargs): 
    4151    """ 
    4252    Use filter() to return a list of objects, or raise a Http404 exception if 
    43     the list is empty. 
     53    the list is emtpy. 
    4454 
    45     klass may be a Model or Manager object.  All other passed 
     55    klass may be a Model, Manager, or QuerySet object.  All other passed 
    4656    arguments and keyword arguments are used in the filter() query. 
    4757    """ 
    48     if isinstance(klass, Manager): 
    49         manager = klass 
    50     else: 
    51         manager = klass._default_manager 
    52     obj_list = list(manager.filter(*args, **kwargs)) 
     58    queryset = _get_queryset(klass) 
     59    obj_list = list(queryset.filter(*args, **kwargs)) 
    5360    if not obj_list: 
    54         raise Http404('No %s matches the given query.' % manager.model._meta.object_name) 
     61        raise Http404('No %s matches the given query.' % queryset.model._meta.object_name) 
    5562    return obj_list 
  • django/trunk/docs/db-api.txt

    r5720 r5746  
    18921892object doesn't exist. This idiom is captured by ``get_object_or_404()``. 
    18931893This function takes a Django model as its first argument and an 
    1894 arbitrary number of keyword arguments, which it passes to the manager's 
    1895 ``get()`` function. It raises ``Http404`` if the object doesn't 
     1894arbitrary number of keyword arguments, which it passes to the default 
     1895manager's ``get()`` function. It raises ``Http404`` if the object doesn't 
    18961896exist. For example:: 
    18971897 
     
    19021902is used to execute the underlying ``get()`` query. If you don't want to 
    19031903use the default manager, or if you want to search a list of related objects, 
    1904 you can provide ``get_object_or_404()`` with a manager object instead. 
     1904you can provide ``get_object_or_404()`` with a ``Manager`` object instead. 
    19051905For example:: 
    19061906 
     
    19111911    # entry with a primary key of 3 
    19121912    e = get_object_or_404(Entry.recent_entries, pk=3) 
     1913 
     1914If you need to use a custom method that you added to a custom manager, 
     1915then you can provide ``get_object_or_404()`` with a ``QuerySet`` object. 
     1916For example:: 
     1917 
     1918    # Use a QuerySet returned from a 'published' method of a custom manager 
     1919    # in the search for an entry with primary key of 5 
     1920    e = get_object_or_404(Entry.objects.published(), pk=5) 
    19131921 
    19141922get_list_or_404() 
  • django/trunk/tests/modeltests/get_object_or_404/models.py

    r5609 r5746  
    44get_object_or_404 is a shortcut function to be used in view functions for 
    55performing a get() lookup and raising a Http404 exception if a DoesNotExist 
    6 exception was rasied during the get() call. 
     6exception was raised during the get() call. 
    77 
    88get_list_or_404 is a shortcut function to be used in view functions for 
    99performing a filter() lookup and raising a Http404 exception if a DoesNotExist 
    10 exception was rasied during the filter() call. 
     10exception was raised during the filter() call. 
    1111""" 
    1212 
     
    7070<Article: Run away!> 
    7171 
     72# QuerySets can be used too. 
     73>>> get_object_or_404(Article.objects.all(), title__contains="Run") 
     74<Article: Run away!> 
     75 
     76# Just as when using a get() lookup, you will get an error if more than one 
     77# object is returned. 
     78>>> get_object_or_404(Author.objects.all()) 
     79Traceback (most recent call last): 
     80... 
     81AssertionError: get() returned more than one Author -- it returned ...! Lookup parameters were {} 
     82 
     83# Using an EmptyQuerySet raises a Http404 error. 
     84>>> get_object_or_404(Article.objects.none(), title__contains="Run") 
     85Traceback (most recent call last): 
     86... 
     87Http404: No Article matches the given query. 
     88 
    7289# get_list_or_404 can be used to get lists of objects 
    7390>>> get_list_or_404(a.article_set, title__icontains='Run') 
    7491[<Article: Run away!>] 
    7592 
    76 # Http404 is returned if the list is empty 
     93# Http404 is returned if the list is empty. 
    7794>>> get_list_or_404(a.article_set, title__icontains='Shrubbery') 
    7895Traceback (most recent call last): 
     
    84101[<Article: Run away!>] 
    85102 
     103# QuerySets can be used too. 
     104>>> get_list_or_404(Article.objects.all(), title__icontains="Run") 
     105[<Article: Run away!>] 
     106 
    86107"""}