diff -r 000000000000 -r 0d40e90630ef web/lib/django/shortcuts/__init__.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/web/lib/django/shortcuts/__init__.py Wed Jan 20 00:34:04 2010 +0100 @@ -0,0 +1,101 @@ +""" +This module collects helper functions and classes that "span" multiple levels +of MVC. In other words, these functions/classes introduce controlled coupling +for convenience's sake. +""" + +from django.template import loader +from django.http import HttpResponse, Http404 +from django.http import HttpResponseRedirect, HttpResponsePermanentRedirect +from django.db.models.manager import Manager +from django.db.models.query import QuerySet +from django.core import urlresolvers + +def render_to_response(*args, **kwargs): + """ + Returns a HttpResponse whose content is filled with the result of calling + django.template.loader.render_to_string() with the passed arguments. + """ + httpresponse_kwargs = {'mimetype': kwargs.pop('mimetype', None)} + return HttpResponse(loader.render_to_string(*args, **kwargs), **httpresponse_kwargs) + +def redirect(to, *args, **kwargs): + """ + Returns an HttpResponseRedirect to the apropriate URL for the arguments + passed. + + The arguments could be: + + * A model: the model's `get_absolute_url()` function will be called. + + * A view name, possibly with arguments: `urlresolvers.reverse()` will + be used to reverse-resolve the name. + + * A URL, which will be used as-is for the redirect location. + + By default issues a temporary redirect; pass permanent=True to issue a + permanent redirect + """ + if kwargs.pop('permanent', False): + redirect_class = HttpResponsePermanentRedirect + else: + redirect_class = HttpResponseRedirect + + # If it's a model, use get_absolute_url() + if hasattr(to, 'get_absolute_url'): + return redirect_class(to.get_absolute_url()) + + # Next try a reverse URL resolution. + try: + return redirect_class(urlresolvers.reverse(to, args=args, kwargs=kwargs)) + except urlresolvers.NoReverseMatch: + # If this doesn't "feel" like a URL, re-raise. + if '/' not in to and '.' not in to: + raise + + # Finally, fall back and assume it's a URL + return redirect_class(to) + +def _get_queryset(klass): + """ + Returns 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): + """ + Uses get() to return an object, or raises a Http404 exception if the object + does not exist. + + 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 MultipleObjectsReturned will be raised if more than one + object is found. + """ + queryset = _get_queryset(klass) + try: + 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): + """ + Uses filter() to return a list of objects, or raise a Http404 exception if + the list is empty. + + klass may be a Model, Manager, or QuerySet object. All other passed + arguments and keyword arguments are used in the filter() query. + """ + queryset = _get_queryset(klass) + obj_list = list(queryset.filter(*args, **kwargs)) + if not obj_list: + raise Http404('No %s matches the given query.' % queryset.model._meta.object_name) + return obj_list \ No newline at end of file