2
This module collects helper functions and classes that "span" multiple levels
3
of MVC. In other words, these functions/classes introduce controlled coupling
4
for convenience's sake.
8
from django.template import loader, RequestContext
9
from django.http import HttpResponse, Http404
10
from django.http import HttpResponseRedirect, HttpResponsePermanentRedirect
11
from django.db.models.base import ModelBase
12
from django.db.models.manager import Manager
13
from django.db.models.query import QuerySet
14
from django.core import urlresolvers
16
def render_to_response(*args, **kwargs):
18
Returns a HttpResponse whose content is filled with the result of calling
19
django.template.loader.render_to_string() with the passed arguments.
21
httpresponse_kwargs = {'content_type': kwargs.pop('content_type', None)}
23
mimetype = kwargs.pop('mimetype', None)
25
warnings.warn("The mimetype keyword argument is deprecated, use "
26
"content_type instead", DeprecationWarning, stacklevel=2)
27
httpresponse_kwargs['content_type'] = mimetype
29
return HttpResponse(loader.render_to_string(*args, **kwargs), **httpresponse_kwargs)
31
def render(request, *args, **kwargs):
33
Returns a HttpResponse whose content is filled with the result of calling
34
django.template.loader.render_to_string() with the passed arguments.
35
Uses a RequestContext by default.
37
httpresponse_kwargs = {
38
'content_type': kwargs.pop('content_type', None),
39
'status': kwargs.pop('status', None),
42
if 'context_instance' in kwargs:
43
context_instance = kwargs.pop('context_instance')
44
if kwargs.get('current_app', None):
45
raise ValueError('If you provide a context_instance you must '
46
'set its current_app before calling render()')
48
current_app = kwargs.pop('current_app', None)
49
context_instance = RequestContext(request, current_app=current_app)
51
kwargs['context_instance'] = context_instance
53
return HttpResponse(loader.render_to_string(*args, **kwargs),
54
**httpresponse_kwargs)
56
def redirect(to, *args, **kwargs):
58
Returns an HttpResponseRedirect to the appropriate URL for the arguments
61
The arguments could be:
63
* A model: the model's `get_absolute_url()` function will be called.
65
* A view name, possibly with arguments: `urlresolvers.reverse()` will
66
be used to reverse-resolve the name.
68
* A URL, which will be used as-is for the redirect location.
70
By default issues a temporary redirect; pass permanent=True to issue a
73
if kwargs.pop('permanent', False):
74
redirect_class = HttpResponsePermanentRedirect
76
redirect_class = HttpResponseRedirect
78
return redirect_class(resolve_url(to, *args, **kwargs))
80
def _get_queryset(klass):
82
Returns a QuerySet from a Model, Manager, or QuerySet. Created to make
83
get_object_or_404 and get_list_or_404 more DRY.
85
Raises a ValueError if klass is not a Model, Manager, or QuerySet.
87
if isinstance(klass, QuerySet):
89
elif isinstance(klass, Manager):
91
elif isinstance(klass, ModelBase):
92
manager = klass._default_manager
94
klass__name = klass.__name__ if isinstance(klass, type) \
95
else klass.__class__.__name__
96
raise ValueError("Object is of type '%s', but must be a Django Model, "
97
"Manager, or QuerySet" % klass__name)
100
def get_object_or_404(klass, *args, **kwargs):
102
Uses get() to return an object, or raises a Http404 exception if the object
105
klass may be a Model, Manager, or QuerySet object. All other passed
106
arguments and keyword arguments are used in the get() query.
108
Note: Like with get(), an MultipleObjectsReturned will be raised if more than one
111
queryset = _get_queryset(klass)
113
return queryset.get(*args, **kwargs)
114
except queryset.model.DoesNotExist:
115
raise Http404('No %s matches the given query.' % queryset.model._meta.object_name)
117
def get_list_or_404(klass, *args, **kwargs):
119
Uses filter() to return a list of objects, or raise a Http404 exception if
122
klass may be a Model, Manager, or QuerySet object. All other passed
123
arguments and keyword arguments are used in the filter() query.
125
queryset = _get_queryset(klass)
126
obj_list = list(queryset.filter(*args, **kwargs))
128
raise Http404('No %s matches the given query.' % queryset.model._meta.object_name)
131
def resolve_url(to, *args, **kwargs):
133
Return a URL appropriate for the arguments passed.
135
The arguments could be:
137
* A model: the model's `get_absolute_url()` function will be called.
139
* A view name, possibly with arguments: `urlresolvers.reverse()` will
140
be used to reverse-resolve the name.
142
* A URL, which will be returned as-is.
145
# If it's a model, use get_absolute_url()
146
if hasattr(to, 'get_absolute_url'):
147
return to.get_absolute_url()
149
# Next try a reverse URL resolution.
151
return urlresolvers.reverse(to, args=args, kwargs=kwargs)
152
except urlresolvers.NoReverseMatch:
153
# If this is a callable, re-raise.
156
# If this doesn't "feel" like a URL, re-raise.
157
if '/' not in to and '.' not in to:
160
# Finally, fall back and assume it's a URL