1 from django.conf import settings
2 from django.contrib.sites.models import Site
3 from django.http import Http404
4 from philo.models import Node, View
7 class LazyNode(object):
8 def __get__(self, request, obj_type=None):
9 if not hasattr(request, '_cached_node_path'):
12 if not hasattr(request, '_found_node'):
14 current_site = Site.objects.get_current()
15 except Site.DoesNotExist:
18 path = request._cached_node_path
19 trailing_slash = False
24 node, subpath = Node.objects.get_with_path(path, root=getattr(current_site, 'root_node', None), absolute_result=False)
25 except Node.DoesNotExist:
30 subpath = "/" + subpath
32 if not node.handles_subpath(subpath):
35 if trailing_slash and subpath[-1] != "/":
38 node.subpath = subpath
40 request._found_node = node
42 return request._found_node
45 class RequestNodeMiddleware(object):
46 """Middleware to process the request's path and attach the closest ancestor node."""
47 def process_request(self, request):
48 request.__class__.node = LazyNode()
50 def process_view(self, request, view_func, view_args, view_kwargs):
52 request._cached_node_path = view_kwargs['path']
56 def process_exception(self, request, exception):
57 if settings.DEBUG or not hasattr(request, 'node') or not request.node:
60 if isinstance(exception, Http404):
61 error_view = request.node.attributes.get('Http404', None)
63 error_view = request.node.attributes.get('Http500', None)
65 if error_view is None or not isinstance(error_view, View):
66 # Should this be duck-typing? Perhaps even no testing?
69 extra_context = {'exception': exception}
70 return error_view.render_to_response(request, extra_context)