def resolve(self, path): ''' Different from Django, this method matches by /app/page/ convention using its pattern. The pattern should create keyword arguments for dmp_app, dmp_page. ''' match = super().resolve(path) if match: try: routing_data = RoutingData( match.kwargs.pop('dmp_app', None) or self.dmp.options['DEFAULT_APP'], match.kwargs.pop('dmp_page', None) or self.dmp.options['DEFAULT_PAGE'], match.kwargs.pop('dmp_function', None) or 'process_request', (match.kwargs.pop('dmp_urlparams', None) or '').strip(), ) if VERSION < (2, 2): return ResolverMatch( RequestViewWrapper(routing_data), match.args, match.kwargs, url_name=match.url_name, app_names=routing_data.app, ) else: return ResolverMatch( RequestViewWrapper(routing_data), match.args, match.kwargs, url_name=match.url_name, app_names=routing_data.app, route=str(self.pattern), ) except ViewDoesNotExist as vdne: # we had a pattern match, but we couldn't get a callable using kwargs from the pattern # create a "pattern" so the programmer can see what happened # this is a hack, but the resolver error page doesn't give other options. # the sad face is to catch the dev's attention in Django's printout msg = "◉︵◉ Pattern matched, but discovery failed: {}".format( vdne) log.exception("%s %s", match.url_name, msg) raise Resolver404({ # this is a bit convoluted, but it makes the PatternStub work with Django 1.x and 2.x 'tried': [[ PatternStub(match.url_name, msg, PatternStub(match.url_name, msg, None)) ]], 'path': path, }) raise Resolver404({'path': path})
def resolve(self, path): ''' First does the regular resolve. If a match is found on the pattern, it then checks whether the named "dmp_router_app" variable is a DMP app. If it is not a DMP app, it raises a Resolver404 indicating that we do not have a match. I'm doing this here in the url resolution instead of within route_request because I need to allow some overlapping patterns like /app and /page. An alternative to this would be to create a set of url patterns for each app. This would prevent this custom resolver, but it would significantly increase the number of url patterns (ugly). And it would only include DMP apps that exist at compile time (and not any that are registered afterward, although I'm not sure when/if this would ever happen). I'm still not sure I made the right decision in choosing this small hack instead of the big set of normal url patterns. But this is the decision for now. Any pattern wrapped in this class MUST have the named parameter: (?P<dmp_router_app>...) ''' # let the super do its work rmatch = super().resolve(path) # if we have a match, check that the dmp_router_app is DMP-enabled if rmatch is not None and not is_dmp_app( rmatch.kwargs['dmp_router_app']): raise Resolver404({'path': path}) # return return rmatch
def __call__(self, scope): # Get the path path = scope.get("path_remaining", scope.get("path", None)) if path is None: raise ValueError( "No 'path' key in connection scope, cannot route URLs") # Remove leading / to match Django's handling path = path.lstrip("/") # Run through the routes we have until one matches for route in self.routes: try: match = route_pattern_match(route, path) if match: new_path, args, kwargs = match # Add args or kwargs into the scope outer = scope.get("url_route", {}) return route.callback( dict( scope, path_remaining=new_path, url_route={ "args": outer.get("args", ()) + args, "kwargs": { **outer.get("kwargs", {}), **kwargs }, }, )) except Resolver404 as e: pass else: if "path_remaining" in scope: raise Resolver404("No route found for path %r." % path) # We are the outermost URLRouter raise ValueError("No route found for path %r." % path)
def complete_service(request, pk=None): try: service = PoolEntrance.objects.get(id=pk) service.leave_date = datetime.now() service.save() return HttpResponseRedirect(reverse('pending-services')) except ObjectDoesNotExist: raise Resolver404('Podano błędne id')
def change_task_status(request, pk=None): try: task = Task.objects.get(id=pk) task.is_done = not task.is_done task.save() return HttpResponseRedirect(reverse('task-list')) except ObjectDoesNotExist: raise Resolver404('Podano błędne id')
def close_visit(request, pk=None): try: record = PoolEntrance.objects.get(id=pk) record.leave_date = datetime.now() record.save() return HttpResponseRedirect(reverse('pool-management')) except ObjectDoesNotExist: raise Resolver404("Podano błędne id")
def get(self, request, *args, **kwargs): page = kwargs['page'] try: self.template_name = self.find_template(page) except TemplateDoesNotExist: raise Resolver404(page) tresp = super(InfoView, self).get(request, *args, **kwargs) response = HttpResponse(tresp.rendered_content) response['Vary'] = 'Cookie' if request.user.is_authenticated: response['Cache-Control'] = 'private' return response
def _resolver_resolve_to_name(resolver, path): tried = [] match = get_regex(resolver).search(path) if match: new_path = path[match.end():] for pattern in resolver.url_patterns: try: if isinstance(pattern, URLPattern): name = _pattern_resolve_to_name(pattern, new_path) elif isinstance(pattern, URLResolver): name = _resolver_resolve_to_name(pattern, new_path) except Resolver404 as e: tr = e.args[0]['tried'] tried.extend( [(get_regex(pattern).pattern + ' ' + t) for t in tr] ) else: if name: return name tried.append(get_regex(pattern).pattern) raise Resolver404({'tried': tried, 'path': new_path})