|
0
|
1 |
""" |
|
|
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. |
|
|
5 |
""" |
|
|
6 |
|
|
|
7 |
from django.template import loader |
|
|
8 |
from django.http import HttpResponse, Http404 |
|
|
9 |
from django.http import HttpResponseRedirect, HttpResponsePermanentRedirect |
|
|
10 |
from django.db.models.manager import Manager |
|
|
11 |
from django.db.models.query import QuerySet |
|
|
12 |
from django.core import urlresolvers |
|
|
13 |
|
|
|
14 |
def render_to_response(*args, **kwargs): |
|
|
15 |
""" |
|
|
16 |
Returns a HttpResponse whose content is filled with the result of calling |
|
|
17 |
django.template.loader.render_to_string() with the passed arguments. |
|
|
18 |
""" |
|
|
19 |
httpresponse_kwargs = {'mimetype': kwargs.pop('mimetype', None)} |
|
|
20 |
return HttpResponse(loader.render_to_string(*args, **kwargs), **httpresponse_kwargs) |
|
|
21 |
|
|
|
22 |
def redirect(to, *args, **kwargs): |
|
|
23 |
""" |
|
|
24 |
Returns an HttpResponseRedirect to the apropriate URL for the arguments |
|
|
25 |
passed. |
|
|
26 |
|
|
|
27 |
The arguments could be: |
|
|
28 |
|
|
|
29 |
* A model: the model's `get_absolute_url()` function will be called. |
|
|
30 |
|
|
|
31 |
* A view name, possibly with arguments: `urlresolvers.reverse()` will |
|
|
32 |
be used to reverse-resolve the name. |
|
|
33 |
|
|
|
34 |
* A URL, which will be used as-is for the redirect location. |
|
|
35 |
|
|
|
36 |
By default issues a temporary redirect; pass permanent=True to issue a |
|
|
37 |
permanent redirect |
|
|
38 |
""" |
|
|
39 |
if kwargs.pop('permanent', False): |
|
|
40 |
redirect_class = HttpResponsePermanentRedirect |
|
|
41 |
else: |
|
|
42 |
redirect_class = HttpResponseRedirect |
|
|
43 |
|
|
|
44 |
# If it's a model, use get_absolute_url() |
|
|
45 |
if hasattr(to, 'get_absolute_url'): |
|
|
46 |
return redirect_class(to.get_absolute_url()) |
|
|
47 |
|
|
|
48 |
# Next try a reverse URL resolution. |
|
|
49 |
try: |
|
|
50 |
return redirect_class(urlresolvers.reverse(to, args=args, kwargs=kwargs)) |
|
|
51 |
except urlresolvers.NoReverseMatch: |
|
|
52 |
# If this doesn't "feel" like a URL, re-raise. |
|
|
53 |
if '/' not in to and '.' not in to: |
|
|
54 |
raise |
|
|
55 |
|
|
|
56 |
# Finally, fall back and assume it's a URL |
|
|
57 |
return redirect_class(to) |
|
|
58 |
|
|
|
59 |
def _get_queryset(klass): |
|
|
60 |
""" |
|
|
61 |
Returns a QuerySet from a Model, Manager, or QuerySet. Created to make |
|
|
62 |
get_object_or_404 and get_list_or_404 more DRY. |
|
|
63 |
""" |
|
|
64 |
if isinstance(klass, QuerySet): |
|
|
65 |
return klass |
|
|
66 |
elif isinstance(klass, Manager): |
|
|
67 |
manager = klass |
|
|
68 |
else: |
|
|
69 |
manager = klass._default_manager |
|
|
70 |
return manager.all() |
|
|
71 |
|
|
|
72 |
def get_object_or_404(klass, *args, **kwargs): |
|
|
73 |
""" |
|
|
74 |
Uses get() to return an object, or raises a Http404 exception if the object |
|
|
75 |
does not exist. |
|
|
76 |
|
|
|
77 |
klass may be a Model, Manager, or QuerySet object. All other passed |
|
|
78 |
arguments and keyword arguments are used in the get() query. |
|
|
79 |
|
|
|
80 |
Note: Like with get(), an MultipleObjectsReturned will be raised if more than one |
|
|
81 |
object is found. |
|
|
82 |
""" |
|
|
83 |
queryset = _get_queryset(klass) |
|
|
84 |
try: |
|
|
85 |
return queryset.get(*args, **kwargs) |
|
|
86 |
except queryset.model.DoesNotExist: |
|
|
87 |
raise Http404('No %s matches the given query.' % queryset.model._meta.object_name) |
|
|
88 |
|
|
|
89 |
def get_list_or_404(klass, *args, **kwargs): |
|
|
90 |
""" |
|
|
91 |
Uses filter() to return a list of objects, or raise a Http404 exception if |
|
|
92 |
the list is empty. |
|
|
93 |
|
|
|
94 |
klass may be a Model, Manager, or QuerySet object. All other passed |
|
|
95 |
arguments and keyword arguments are used in the filter() query. |
|
|
96 |
""" |
|
|
97 |
queryset = _get_queryset(klass) |
|
|
98 |
obj_list = list(queryset.filter(*args, **kwargs)) |
|
|
99 |
if not obj_list: |
|
|
100 |
raise Http404('No %s matches the given query.' % queryset.model._meta.object_name) |
|
|
101 |
return obj_list |