| 76 | def _get_response(self, request, urlconf, resolver, url_patterns=None): |
| 77 | "Returns an HttpResponse object for the given HttpRequest" |
| 78 | from django.core import exceptions, urlresolvers |
| 79 | from django.conf import settings |
| 80 | |
| 81 | try: |
| 82 | response = None |
| 83 | # Apply request middleware |
| 84 | for middleware_method in self._request_middleware: |
| 85 | response = middleware_method(request) |
| 86 | if response: |
| 87 | break |
| 88 | |
| 89 | if response is None: |
| 90 | if hasattr(request, "urlconf"): |
| 91 | # Reset url resolver with a custom urlconf. |
| 92 | urlconf = request.urlconf |
| 93 | urlresolvers.set_urlconf(urlconf) |
| 94 | resolver = urlresolvers.RegexURLResolver(r'^/', urlconf) |
| 95 | |
| 96 | callback, callback_args, callback_kwargs = resolver.resolve( |
| 97 | request.path_info, url_patterns=url_patterns) |
| 98 | |
| 99 | # Apply view middleware |
| 100 | for middleware_method in self._view_middleware: |
| 101 | response = middleware_method(request, callback, callback_args, callback_kwargs) |
| 102 | if response: |
| 103 | break |
| 104 | |
| 105 | if response is None: |
| 106 | try: |
| 107 | response = callback(request, *callback_args, **callback_kwargs) |
| 108 | except urlresolvers.DoesNotResolve, e: |
| 109 | return self._get_response(request, urlconf, resolver, url_patterns=url_patterns) |
| 110 | except Exception as e: |
| 111 | # If the view raised an exception, run it through exception |
| 112 | # middleware, and if the exception middleware returns a |
| 113 | # response, use that. Otherwise, reraise the exception. |
| 114 | for middleware_method in self._exception_middleware: |
| 115 | response = middleware_method(request, e) |
| 116 | if response: |
| 117 | break |
| 118 | if response is None: |
| 119 | raise |
| 120 | |
| 121 | # Complain if the view returned None (a common error). |
| 122 | if response is None: |
| 123 | if isinstance(callback, types.FunctionType): # FBV |
| 124 | view_name = callback.__name__ |
| 125 | else: # CBV |
| 126 | view_name = callback.__class__.__name__ + '.__call__' |
| 127 | raise ValueError("The view %s.%s didn't return an HttpResponse object." % (callback.__module__, view_name)) |
| 128 | |
| 129 | # If the response supports deferred rendering, apply template |
| 130 | # response middleware and the render the response |
| 131 | if hasattr(response, 'render') and callable(response.render): |
| 132 | for middleware_method in self._template_response_middleware: |
| 133 | response = middleware_method(request, response) |
| 134 | response = response.render() |
| 135 | |
| 136 | except http.Http404 as e: |
| 137 | logger.warning('Not Found: %s', request.path, |
| 138 | extra={ |
| 139 | 'status_code': 404, |
| 140 | 'request': request |
| 141 | }) |
| 142 | if settings.DEBUG: |
| 143 | from django.views import debug |
| 144 | response = debug.technical_404_response(request, e) |
| 145 | else: |
| 146 | try: |
| 147 | callback, param_dict = resolver.resolve404() |
| 148 | response = callback(request, **param_dict) |
| 149 | except: |
| 150 | signals.got_request_exception.send(sender=self.__class__, request=request) |
| 151 | response = self.handle_uncaught_exception(request, resolver, sys.exc_info()) |
| 152 | except exceptions.PermissionDenied: |
| 153 | logger.warning( |
| 154 | 'Forbidden (Permission denied): %s', request.path, |
| 155 | extra={ |
| 156 | 'status_code': 403, |
| 157 | 'request': request |
| 158 | }) |
| 159 | try: |
| 160 | callback, param_dict = resolver.resolve403() |
| 161 | response = callback(request, **param_dict) |
| 162 | except: |
| 163 | signals.got_request_exception.send( |
| 164 | sender=self.__class__, request=request) |
| 165 | response = self.handle_uncaught_exception(request, |
| 166 | resolver, sys.exc_info()) |
| 167 | except SystemExit: |
| 168 | # Allow sys.exit() to actually exit. See tickets #1023 and #4701 |
| 169 | raise |
| 170 | except: # Handle everything else, including SuspiciousOperation, etc. |
| 171 | # Get the exception info now, in case another exception is thrown later. |
| 172 | signals.got_request_exception.send(sender=self.__class__, request=request) |
| 173 | response = self.handle_uncaught_exception(request, resolver, sys.exc_info()) |
| 174 | return response |
| 175 | |
104 | | callback, callback_args, callback_kwargs = resolver.resolve( |
105 | | request.path_info) |
106 | | |
107 | | # Apply view middleware |
108 | | for middleware_method in self._view_middleware: |
109 | | response = middleware_method(request, callback, callback_args, callback_kwargs) |
110 | | if response: |
111 | | break |
112 | | |
113 | | if response is None: |
114 | | try: |
115 | | response = callback(request, *callback_args, **callback_kwargs) |
116 | | except Exception as e: |
117 | | # If the view raised an exception, run it through exception |
118 | | # middleware, and if the exception middleware returns a |
119 | | # response, use that. Otherwise, reraise the exception. |
120 | | for middleware_method in self._exception_middleware: |
121 | | response = middleware_method(request, e) |
122 | | if response: |
123 | | break |
124 | | if response is None: |
125 | | raise |
126 | | |
127 | | # Complain if the view returned None (a common error). |
128 | | if response is None: |
129 | | if isinstance(callback, types.FunctionType): # FBV |
130 | | view_name = callback.__name__ |
131 | | else: # CBV |
132 | | view_name = callback.__class__.__name__ + '.__call__' |
133 | | raise ValueError("The view %s.%s didn't return an HttpResponse object." % (callback.__module__, view_name)) |
134 | | |
135 | | # If the response supports deferred rendering, apply template |
136 | | # response middleware and the render the response |
137 | | if hasattr(response, 'render') and callable(response.render): |
138 | | for middleware_method in self._template_response_middleware: |
139 | | response = middleware_method(request, response) |
140 | | response = response.render() |
141 | | |
142 | | except http.Http404 as e: |
143 | | logger.warning('Not Found: %s', request.path, |
144 | | extra={ |
145 | | 'status_code': 404, |
146 | | 'request': request |
147 | | }) |
148 | | if settings.DEBUG: |
149 | | from django.views import debug |
150 | | response = debug.technical_404_response(request, e) |
151 | | else: |
152 | | try: |
153 | | callback, param_dict = resolver.resolve404() |
154 | | response = callback(request, **param_dict) |
155 | | except: |
156 | | signals.got_request_exception.send(sender=self.__class__, request=request) |
157 | | response = self.handle_uncaught_exception(request, resolver, sys.exc_info()) |
158 | | except exceptions.PermissionDenied: |
159 | | logger.warning( |
160 | | 'Forbidden (Permission denied): %s', request.path, |
161 | | extra={ |
162 | | 'status_code': 403, |
163 | | 'request': request |
164 | | }) |
165 | | try: |
166 | | callback, param_dict = resolver.resolve403() |
167 | | response = callback(request, **param_dict) |
168 | | except: |
169 | | signals.got_request_exception.send( |
170 | | sender=self.__class__, request=request) |
171 | | response = self.handle_uncaught_exception(request, |
172 | | resolver, sys.exc_info()) |
173 | | except SystemExit: |
174 | | # Allow sys.exit() to actually exit. See tickets #1023 and #4701 |
175 | | raise |
176 | | except: # Handle everything else, including SuspiciousOperation, etc. |
177 | | # Get the exception info now, in case another exception is thrown later. |
178 | | signals.got_request_exception.send(sender=self.__class__, request=request) |
179 | | response = self.handle_uncaught_exception(request, resolver, sys.exc_info()) |