Coverage for multiurl.py: 30%
59 statements
« prev ^ index » next coverage.py v7.2.2, created at 2023-06-07 15:55 +0200
« prev ^ index » next coverage.py v7.2.2, created at 2023-06-07 15:55 +0200
1from __future__ import unicode_literals
3try:
4 from django import urls as urlresolvers
5 from django.urls.resolvers import RegexPattern
6except ImportError:
7 # Fallbacks and mocks for Django 1.*
8 from django.core import urlresolvers
10 urlresolvers.URLResolver = urlresolvers.RegexURLResolver
12 def RegexPattern(pattern):
13 return pattern
16class ContinueResolving(Exception):
17 pass
20def multiurl(*urls, **kwargs):
21 exceptions = kwargs.get('catch', (ContinueResolving,))
22 return MultiRegexURLResolver(urls, exceptions)
25class MultiRegexURLResolver(urlresolvers.URLResolver):
26 def __init__(self, urls, exceptions):
27 super(MultiRegexURLResolver, self).__init__(RegexPattern(''), None)
28 self._urls = urls
29 self._exceptions = exceptions
31 @property
32 def url_patterns(self):
33 return self._urls
35 def resolve(self, path):
36 tried = []
37 matched = []
38 patterns_matched = []
40 # This is a simplified version of RegexURLResolver. It doesn't
41 # support a regex prefix, and it doesn't need to handle include(),
42 # so it's simplier, but otherwise this is mostly a copy/paste.
43 for pattern in self.url_patterns:
44 sub_match = pattern.resolve(path)
45 if sub_match:
46 # Here's the part that's different: instead of returning the
47 # first match, build up a list of all matches.
48 rm = urlresolvers.ResolverMatch(sub_match.func, sub_match.args, sub_match.kwargs, sub_match.url_name)
49 matched.append(rm)
50 patterns_matched.append([pattern])
51 tried.append([pattern])
52 if matched:
53 return MultiResolverMatch(matched, self._exceptions, patterns_matched, path)
54 raise urlresolvers.Resolver404({'tried': tried, 'path': path})
57class MultiResolverMatch(object):
58 def __init__(self, matches, exceptions, patterns_matched, path, route='', tried=None):
59 self.matches = matches
60 self.exceptions = exceptions
61 self.patterns_matched = patterns_matched
62 self.path = path
63 self.route = route
64 self.tried = tried
66 # Attributes to emulate ResolverMatch
67 self.kwargs = {}
68 self.args = ()
69 self.url_name = None
70 self.app_names = []
71 self.app_name = None
72 self.namespaces = []
74 @property
75 def func(self):
76 def multiview(request):
77 for i, match in enumerate(self.matches):
78 try:
79 return match.func(request, *match.args, **match.kwargs)
80 except self.exceptions:
81 continue
82 raise urlresolvers.Resolver404({'tried': self.patterns_matched, 'path': self.path})
83 multiview.multi_resolver_match = self
84 return multiview