1 from django.conf import settings
2 from django.contrib.sites.models import Site
3 from django.http import Http404
5 from philo.models import Node, View
8 class LazyNode(object):
9 def __get__(self, request, obj_type=None):
10 if not hasattr(request, '_cached_node_path'):
13 if not hasattr(request, '_found_node'):
15 current_site = Site.objects.get_current()
16 except Site.DoesNotExist:
19 path = request._cached_node_path
20 trailing_slash = False
25 node, subpath = Node.objects.get_with_path(path, root=getattr(current_site, 'root_node', None), absolute_result=False)
26 except Node.DoesNotExist:
31 subpath = "/" + subpath
33 if not node.handles_subpath(subpath):
36 if trailing_slash and subpath[-1] != "/":
39 node.subpath = subpath
41 request._found_node = node
43 return request._found_node
46 class RequestNodeMiddleware(object):
47 """Middleware to process the request's path and attach the closest ancestor node."""
48 def process_request(self, request):
49 request.__class__.node = LazyNode()
51 def process_view(self, request, view_func, view_args, view_kwargs):
53 request._cached_node_path = view_kwargs['path']
57 def process_exception(self, request, exception):
58 if settings.DEBUG or not hasattr(request, 'node') or not request.node:
61 if isinstance(exception, Http404):
62 error_view = request.node.attributes.get('Http404', None)
64 error_view = request.node.attributes.get('Http500', None)
66 if error_view is None or not isinstance(error_view, View):
67 # Should this be duck-typing? Perhaps even no testing?
70 extra_context = {'exception': exception}
71 return error_view.render_to_response(request, extra_context)