测试gitnore
This commit is contained in:
@@ -10,7 +10,6 @@ import inspect
|
||||
import re
|
||||
import string
|
||||
from importlib import import_module
|
||||
from pickle import PicklingError
|
||||
from urllib.parse import quote
|
||||
|
||||
from asgiref.local import Local
|
||||
@@ -31,17 +30,7 @@ from .utils import get_callable
|
||||
|
||||
|
||||
class ResolverMatch:
|
||||
def __init__(
|
||||
self,
|
||||
func,
|
||||
args,
|
||||
kwargs,
|
||||
url_name=None,
|
||||
app_names=None,
|
||||
namespaces=None,
|
||||
route=None,
|
||||
tried=None,
|
||||
):
|
||||
def __init__(self, func, args, kwargs, url_name=None, app_names=None, namespaces=None, route=None, tried=None):
|
||||
self.func = func
|
||||
self.args = args
|
||||
self.kwargs = kwargs
|
||||
@@ -52,47 +41,29 @@ class ResolverMatch:
|
||||
# If a URLRegexResolver doesn't have a namespace or app_name, it passes
|
||||
# in an empty value.
|
||||
self.app_names = [x for x in app_names if x] if app_names else []
|
||||
self.app_name = ":".join(self.app_names)
|
||||
self.app_name = ':'.join(self.app_names)
|
||||
self.namespaces = [x for x in namespaces if x] if namespaces else []
|
||||
self.namespace = ":".join(self.namespaces)
|
||||
self.namespace = ':'.join(self.namespaces)
|
||||
|
||||
if hasattr(func, "view_class"):
|
||||
func = func.view_class
|
||||
if not hasattr(func, "__name__"):
|
||||
if not hasattr(func, '__name__'):
|
||||
# A class-based view
|
||||
self._func_path = func.__class__.__module__ + "." + func.__class__.__name__
|
||||
self._func_path = func.__class__.__module__ + '.' + func.__class__.__name__
|
||||
else:
|
||||
# A function-based view
|
||||
self._func_path = func.__module__ + "." + func.__name__
|
||||
self._func_path = func.__module__ + '.' + func.__name__
|
||||
|
||||
view_path = url_name or self._func_path
|
||||
self.view_name = ":".join(self.namespaces + [view_path])
|
||||
self.view_name = ':'.join(self.namespaces + [view_path])
|
||||
|
||||
def __getitem__(self, index):
|
||||
return (self.func, self.args, self.kwargs)[index]
|
||||
|
||||
def __repr__(self):
|
||||
if isinstance(self.func, functools.partial):
|
||||
func = repr(self.func)
|
||||
else:
|
||||
func = self._func_path
|
||||
return (
|
||||
"ResolverMatch(func=%s, args=%r, kwargs=%r, url_name=%r, "
|
||||
"app_names=%r, namespaces=%r, route=%r)"
|
||||
% (
|
||||
func,
|
||||
self.args,
|
||||
self.kwargs,
|
||||
self.url_name,
|
||||
self.app_names,
|
||||
self.namespaces,
|
||||
self.route,
|
||||
)
|
||||
return "ResolverMatch(func=%s, args=%s, kwargs=%s, url_name=%s, app_names=%s, namespaces=%s, route=%s)" % (
|
||||
self._func_path, self.args, self.kwargs, self.url_name,
|
||||
self.app_names, self.namespaces, self.route,
|
||||
)
|
||||
|
||||
def __reduce_ex__(self, protocol):
|
||||
raise PicklingError(f"Cannot pickle {self.__class__.__qualname__}.")
|
||||
|
||||
|
||||
def get_resolver(urlconf=None):
|
||||
if urlconf is None:
|
||||
@@ -102,7 +73,7 @@ def get_resolver(urlconf=None):
|
||||
|
||||
@functools.lru_cache(maxsize=None)
|
||||
def _get_cached_resolver(urlconf=None):
|
||||
return URLResolver(RegexPattern(r"^/"), urlconf)
|
||||
return URLResolver(RegexPattern(r'^/'), urlconf)
|
||||
|
||||
|
||||
@functools.lru_cache(maxsize=None)
|
||||
@@ -113,7 +84,7 @@ def get_ns_resolver(ns_pattern, resolver, converters):
|
||||
pattern = RegexPattern(ns_pattern)
|
||||
pattern.converters = dict(converters)
|
||||
ns_resolver = URLResolver(pattern, resolver.url_patterns)
|
||||
return URLResolver(RegexPattern(r"^/"), [ns_resolver])
|
||||
return URLResolver(RegexPattern(r'^/'), [ns_resolver])
|
||||
|
||||
|
||||
class LocaleRegexDescriptor:
|
||||
@@ -131,8 +102,8 @@ class LocaleRegexDescriptor:
|
||||
# avoid per-language compilation.
|
||||
pattern = getattr(instance, self.attr)
|
||||
if isinstance(pattern, str):
|
||||
instance.__dict__["regex"] = instance._compile(pattern)
|
||||
return instance.__dict__["regex"]
|
||||
instance.__dict__['regex'] = instance._compile(pattern)
|
||||
return instance.__dict__['regex']
|
||||
language_code = get_language()
|
||||
if language_code not in instance._regex_dict:
|
||||
instance._regex_dict[language_code] = instance._compile(str(pattern))
|
||||
@@ -158,9 +129,7 @@ class CheckURLMixin:
|
||||
# Skip check as it can be useful to start a URL pattern with a slash
|
||||
# when APPEND_SLASH=False.
|
||||
return []
|
||||
if regex_pattern.startswith(("/", "^/", "^\\/")) and not regex_pattern.endswith(
|
||||
"/"
|
||||
):
|
||||
if regex_pattern.startswith(('/', '^/', '^\\/')) and not regex_pattern.endswith('/'):
|
||||
warning = Warning(
|
||||
"Your URL pattern {} has a route beginning with a '/'. Remove this "
|
||||
"slash as it is unnecessary. If this pattern is targeted in an "
|
||||
@@ -175,7 +144,7 @@ class CheckURLMixin:
|
||||
|
||||
|
||||
class RegexPattern(CheckURLMixin):
|
||||
regex = LocaleRegexDescriptor("_regex")
|
||||
regex = LocaleRegexDescriptor('_regex')
|
||||
|
||||
def __init__(self, regex, name=None, is_endpoint=False):
|
||||
self._regex = regex
|
||||
@@ -185,11 +154,7 @@ class RegexPattern(CheckURLMixin):
|
||||
self.converters = {}
|
||||
|
||||
def match(self, path):
|
||||
match = (
|
||||
self.regex.fullmatch(path)
|
||||
if self._is_endpoint and self.regex.pattern.endswith("$")
|
||||
else self.regex.search(path)
|
||||
)
|
||||
match = self.regex.search(path)
|
||||
if match:
|
||||
# If there are any named groups, use those as kwargs, ignoring
|
||||
# non-named groups. Otherwise, pass all non-named arguments as
|
||||
@@ -197,7 +162,7 @@ class RegexPattern(CheckURLMixin):
|
||||
kwargs = match.groupdict()
|
||||
args = () if kwargs else match.groups()
|
||||
kwargs = {k: v for k, v in kwargs.items() if v is not None}
|
||||
return path[match.end() :], args, kwargs
|
||||
return path[match.end():], args, kwargs
|
||||
return None
|
||||
|
||||
def check(self):
|
||||
@@ -209,15 +174,13 @@ class RegexPattern(CheckURLMixin):
|
||||
|
||||
def _check_include_trailing_dollar(self):
|
||||
regex_pattern = self.regex.pattern
|
||||
if regex_pattern.endswith("$") and not regex_pattern.endswith(r"\$"):
|
||||
return [
|
||||
Warning(
|
||||
"Your URL pattern {} uses include with a route ending with a '$'. "
|
||||
"Remove the dollar from the route to avoid problems including "
|
||||
"URLs.".format(self.describe()),
|
||||
id="urls.W001",
|
||||
)
|
||||
]
|
||||
if regex_pattern.endswith('$') and not regex_pattern.endswith(r'\$'):
|
||||
return [Warning(
|
||||
"Your URL pattern {} uses include with a route ending with a '$'. "
|
||||
"Remove the dollar from the route to avoid problems including "
|
||||
"URLs.".format(self.describe()),
|
||||
id='urls.W001',
|
||||
)]
|
||||
else:
|
||||
return []
|
||||
|
||||
@@ -235,7 +198,7 @@ class RegexPattern(CheckURLMixin):
|
||||
|
||||
|
||||
_PATH_PARAMETER_COMPONENT_RE = _lazy_re_compile(
|
||||
r"<(?:(?P<converter>[^>:]+):)?(?P<parameter>[^>]+)>"
|
||||
r'<(?:(?P<converter>[^>:]+):)?(?P<parameter>[^>]+)>'
|
||||
)
|
||||
|
||||
|
||||
@@ -247,7 +210,7 @@ def _route_to_regex(route, is_endpoint=False):
|
||||
and {'pk': <django.urls.converters.IntConverter>}.
|
||||
"""
|
||||
original_route = route
|
||||
parts = ["^"]
|
||||
parts = ['^']
|
||||
converters = {}
|
||||
while True:
|
||||
match = _PATH_PARAMETER_COMPONENT_RE.search(route)
|
||||
@@ -259,34 +222,34 @@ def _route_to_regex(route, is_endpoint=False):
|
||||
"URL route '%s' cannot contain whitespace in angle brackets "
|
||||
"<…>." % original_route
|
||||
)
|
||||
parts.append(re.escape(route[: match.start()]))
|
||||
route = route[match.end() :]
|
||||
parameter = match["parameter"]
|
||||
parts.append(re.escape(route[:match.start()]))
|
||||
route = route[match.end():]
|
||||
parameter = match['parameter']
|
||||
if not parameter.isidentifier():
|
||||
raise ImproperlyConfigured(
|
||||
"URL route '%s' uses parameter name %r which isn't a valid "
|
||||
"Python identifier." % (original_route, parameter)
|
||||
)
|
||||
raw_converter = match["converter"]
|
||||
raw_converter = match['converter']
|
||||
if raw_converter is None:
|
||||
# If a converter isn't specified, the default is `str`.
|
||||
raw_converter = "str"
|
||||
raw_converter = 'str'
|
||||
try:
|
||||
converter = get_converter(raw_converter)
|
||||
except KeyError as e:
|
||||
raise ImproperlyConfigured(
|
||||
"URL route %r uses invalid converter %r."
|
||||
'URL route %r uses invalid converter %r.'
|
||||
% (original_route, raw_converter)
|
||||
) from e
|
||||
converters[parameter] = converter
|
||||
parts.append("(?P<" + parameter + ">" + converter.regex + ")")
|
||||
parts.append('(?P<' + parameter + '>' + converter.regex + ')')
|
||||
if is_endpoint:
|
||||
parts.append(r"\Z")
|
||||
return "".join(parts), converters
|
||||
parts.append('$')
|
||||
return ''.join(parts), converters
|
||||
|
||||
|
||||
class RoutePattern(CheckURLMixin):
|
||||
regex = LocaleRegexDescriptor("_route")
|
||||
regex = LocaleRegexDescriptor('_route')
|
||||
|
||||
def __init__(self, route, name=None, is_endpoint=False):
|
||||
self._route = route
|
||||
@@ -306,21 +269,19 @@ class RoutePattern(CheckURLMixin):
|
||||
kwargs[key] = converter.to_python(value)
|
||||
except ValueError:
|
||||
return None
|
||||
return path[match.end() :], (), kwargs
|
||||
return path[match.end():], (), kwargs
|
||||
return None
|
||||
|
||||
def check(self):
|
||||
warnings = self._check_pattern_startswith_slash()
|
||||
route = self._route
|
||||
if "(?P<" in route or route.startswith("^") or route.endswith("$"):
|
||||
warnings.append(
|
||||
Warning(
|
||||
"Your URL pattern {} has a route that contains '(?P<', begins "
|
||||
"with a '^', or ends with a '$'. This was likely an oversight "
|
||||
"when migrating to django.urls.path().".format(self.describe()),
|
||||
id="2_0.W001",
|
||||
)
|
||||
)
|
||||
if '(?P<' in route or route.startswith('^') or route.endswith('$'):
|
||||
warnings.append(Warning(
|
||||
"Your URL pattern {} has a route that contains '(?P<', begins "
|
||||
"with a '^', or ends with a '$'. This was likely an oversight "
|
||||
"when migrating to django.urls.path().".format(self.describe()),
|
||||
id='2_0.W001',
|
||||
))
|
||||
return warnings
|
||||
|
||||
def _compile(self, route):
|
||||
@@ -344,14 +305,14 @@ class LocalePrefixPattern:
|
||||
def language_prefix(self):
|
||||
language_code = get_language() or settings.LANGUAGE_CODE
|
||||
if language_code == settings.LANGUAGE_CODE and not self.prefix_default_language:
|
||||
return ""
|
||||
return ''
|
||||
else:
|
||||
return "%s/" % language_code
|
||||
return '%s/' % language_code
|
||||
|
||||
def match(self, path):
|
||||
language_prefix = self.language_prefix
|
||||
if path.startswith(language_prefix):
|
||||
return path[len(language_prefix) :], (), {}
|
||||
return path[len(language_prefix):], (), {}
|
||||
return None
|
||||
|
||||
def check(self):
|
||||
@@ -372,12 +333,11 @@ class URLPattern:
|
||||
self.name = name
|
||||
|
||||
def __repr__(self):
|
||||
return "<%s %s>" % (self.__class__.__name__, self.pattern.describe())
|
||||
return '<%s %s>' % (self.__class__.__name__, self.pattern.describe())
|
||||
|
||||
def check(self):
|
||||
warnings = self._check_pattern_name()
|
||||
warnings.extend(self.pattern.check())
|
||||
warnings.extend(self._check_callback())
|
||||
return warnings
|
||||
|
||||
def _check_pattern_name(self):
|
||||
@@ -394,34 +354,13 @@ class URLPattern:
|
||||
else:
|
||||
return []
|
||||
|
||||
def _check_callback(self):
|
||||
from django.views import View
|
||||
|
||||
view = self.callback
|
||||
if inspect.isclass(view) and issubclass(view, View):
|
||||
return [
|
||||
Error(
|
||||
"Your URL pattern %s has an invalid view, pass %s.as_view() "
|
||||
"instead of %s."
|
||||
% (
|
||||
self.pattern.describe(),
|
||||
view.__name__,
|
||||
view.__name__,
|
||||
),
|
||||
id="urls.E009",
|
||||
)
|
||||
]
|
||||
return []
|
||||
|
||||
def resolve(self, path):
|
||||
match = self.pattern.match(path)
|
||||
if match:
|
||||
new_path, args, kwargs = match
|
||||
# Pass any extra_kwargs as **kwargs.
|
||||
kwargs.update(self.default_args)
|
||||
return ResolverMatch(
|
||||
self.callback, args, kwargs, self.pattern.name, route=str(self.pattern)
|
||||
)
|
||||
return ResolverMatch(self.callback, args, kwargs, self.pattern.name, route=str(self.pattern))
|
||||
|
||||
@cached_property
|
||||
def lookup_str(self):
|
||||
@@ -432,17 +371,13 @@ class URLPattern:
|
||||
callback = self.callback
|
||||
if isinstance(callback, functools.partial):
|
||||
callback = callback.func
|
||||
if hasattr(callback, "view_class"):
|
||||
callback = callback.view_class
|
||||
elif not hasattr(callback, "__name__"):
|
||||
if not hasattr(callback, '__name__'):
|
||||
return callback.__module__ + "." + callback.__class__.__name__
|
||||
return callback.__module__ + "." + callback.__qualname__
|
||||
|
||||
|
||||
class URLResolver:
|
||||
def __init__(
|
||||
self, pattern, urlconf_name, default_kwargs=None, app_name=None, namespace=None
|
||||
):
|
||||
def __init__(self, pattern, urlconf_name, default_kwargs=None, app_name=None, namespace=None):
|
||||
self.pattern = pattern
|
||||
# urlconf_name is the dotted Python path to the module defining
|
||||
# urlpatterns. It may also be an object with an urlpatterns attribute
|
||||
@@ -464,15 +399,12 @@ class URLResolver:
|
||||
def __repr__(self):
|
||||
if isinstance(self.urlconf_name, list) and self.urlconf_name:
|
||||
# Don't bother to output the whole list, it can be huge
|
||||
urlconf_repr = "<%s list>" % self.urlconf_name[0].__class__.__name__
|
||||
urlconf_repr = '<%s list>' % self.urlconf_name[0].__class__.__name__
|
||||
else:
|
||||
urlconf_repr = repr(self.urlconf_name)
|
||||
return "<%s %s (%s:%s) %s>" % (
|
||||
self.__class__.__name__,
|
||||
urlconf_repr,
|
||||
self.app_name,
|
||||
self.namespace,
|
||||
self.pattern.describe(),
|
||||
return '<%s %s (%s:%s) %s>' % (
|
||||
self.__class__.__name__, urlconf_repr, self.app_name,
|
||||
self.namespace, self.pattern.describe(),
|
||||
)
|
||||
|
||||
def check(self):
|
||||
@@ -490,12 +422,11 @@ class URLResolver:
|
||||
try:
|
||||
handler = self.resolve_error_handler(status_code)
|
||||
except (ImportError, ViewDoesNotExist) as e:
|
||||
path = getattr(self.urlconf_module, "handler%s" % status_code)
|
||||
path = getattr(self.urlconf_module, 'handler%s' % status_code)
|
||||
msg = (
|
||||
"The custom handler{status_code} view '{path}' could not be "
|
||||
"imported."
|
||||
"The custom handler{status_code} view '{path}' could not be imported."
|
||||
).format(status_code=status_code, path=path)
|
||||
messages.append(Error(msg, hint=str(e), id="urls.E008"))
|
||||
messages.append(Error(msg, hint=str(e), id='urls.E008'))
|
||||
continue
|
||||
signature = inspect.signature(handler)
|
||||
args = [None] * num_parameters
|
||||
@@ -507,10 +438,10 @@ class URLResolver:
|
||||
"take the correct number of arguments ({args})."
|
||||
).format(
|
||||
status_code=status_code,
|
||||
path=handler.__module__ + "." + handler.__qualname__,
|
||||
args="request, exception" if num_parameters == 2 else "request",
|
||||
path=handler.__module__ + '.' + handler.__qualname__,
|
||||
args='request, exception' if num_parameters == 2 else 'request',
|
||||
)
|
||||
messages.append(Error(msg, id="urls.E007"))
|
||||
messages.append(Error(msg, id='urls.E007'))
|
||||
return messages
|
||||
|
||||
def _populate(self):
|
||||
@@ -518,7 +449,7 @@ class URLResolver:
|
||||
# infinite recursion. Concurrent threads may call this at the same
|
||||
# time and will need to continue, so set 'populating' on a
|
||||
# thread-local variable.
|
||||
if getattr(self._local, "populating", False):
|
||||
if getattr(self._local, 'populating', False):
|
||||
return
|
||||
try:
|
||||
self._local.populating = True
|
||||
@@ -528,45 +459,28 @@ class URLResolver:
|
||||
language_code = get_language()
|
||||
for url_pattern in reversed(self.url_patterns):
|
||||
p_pattern = url_pattern.pattern.regex.pattern
|
||||
if p_pattern.startswith("^"):
|
||||
if p_pattern.startswith('^'):
|
||||
p_pattern = p_pattern[1:]
|
||||
if isinstance(url_pattern, URLPattern):
|
||||
self._callback_strs.add(url_pattern.lookup_str)
|
||||
bits = normalize(url_pattern.pattern.regex.pattern)
|
||||
lookups.appendlist(
|
||||
url_pattern.callback,
|
||||
(
|
||||
bits,
|
||||
p_pattern,
|
||||
url_pattern.default_args,
|
||||
url_pattern.pattern.converters,
|
||||
),
|
||||
(bits, p_pattern, url_pattern.default_args, url_pattern.pattern.converters)
|
||||
)
|
||||
if url_pattern.name is not None:
|
||||
lookups.appendlist(
|
||||
url_pattern.name,
|
||||
(
|
||||
bits,
|
||||
p_pattern,
|
||||
url_pattern.default_args,
|
||||
url_pattern.pattern.converters,
|
||||
),
|
||||
(bits, p_pattern, url_pattern.default_args, url_pattern.pattern.converters)
|
||||
)
|
||||
else: # url_pattern is a URLResolver.
|
||||
url_pattern._populate()
|
||||
if url_pattern.app_name:
|
||||
apps.setdefault(url_pattern.app_name, []).append(
|
||||
url_pattern.namespace
|
||||
)
|
||||
apps.setdefault(url_pattern.app_name, []).append(url_pattern.namespace)
|
||||
namespaces[url_pattern.namespace] = (p_pattern, url_pattern)
|
||||
else:
|
||||
for name in url_pattern.reverse_dict:
|
||||
for (
|
||||
matches,
|
||||
pat,
|
||||
defaults,
|
||||
converters,
|
||||
) in url_pattern.reverse_dict.getlist(name):
|
||||
for matches, pat, defaults, converters in url_pattern.reverse_dict.getlist(name):
|
||||
new_matches = normalize(p_pattern + pat)
|
||||
lookups.appendlist(
|
||||
name,
|
||||
@@ -574,17 +488,10 @@ class URLResolver:
|
||||
new_matches,
|
||||
p_pattern + pat,
|
||||
{**defaults, **url_pattern.default_kwargs},
|
||||
{
|
||||
**self.pattern.converters,
|
||||
**url_pattern.pattern.converters,
|
||||
**converters,
|
||||
},
|
||||
),
|
||||
{**self.pattern.converters, **url_pattern.pattern.converters, **converters}
|
||||
)
|
||||
)
|
||||
for namespace, (
|
||||
prefix,
|
||||
sub_pattern,
|
||||
) in url_pattern.namespace_dict.items():
|
||||
for namespace, (prefix, sub_pattern) in url_pattern.namespace_dict.items():
|
||||
current_converters = url_pattern.pattern.converters
|
||||
sub_pattern.pattern.converters.update(current_converters)
|
||||
namespaces[namespace] = (p_pattern + prefix, sub_pattern)
|
||||
@@ -631,7 +538,7 @@ class URLResolver:
|
||||
"""Join two routes, without the starting ^ in the second route."""
|
||||
if not route1:
|
||||
return route2
|
||||
if route2.startswith("^"):
|
||||
if route2.startswith('^'):
|
||||
route2 = route2[1:]
|
||||
return route1 + route2
|
||||
|
||||
@@ -650,7 +557,7 @@ class URLResolver:
|
||||
try:
|
||||
sub_match = pattern.resolve(new_path)
|
||||
except Resolver404 as e:
|
||||
self._extend_tried(tried, pattern, e.args[0].get("tried"))
|
||||
self._extend_tried(tried, pattern, e.args[0].get('tried'))
|
||||
else:
|
||||
if sub_match:
|
||||
# Merge captured arguments in match with submatch
|
||||
@@ -658,16 +565,11 @@ class URLResolver:
|
||||
# Update the sub_match_dict with the kwargs from the sub_match.
|
||||
sub_match_dict.update(sub_match.kwargs)
|
||||
# If there are *any* named groups, ignore all non-named groups.
|
||||
# Otherwise, pass all non-named arguments as positional
|
||||
# arguments.
|
||||
# Otherwise, pass all non-named arguments as positional arguments.
|
||||
sub_match_args = sub_match.args
|
||||
if not sub_match_dict:
|
||||
sub_match_args = args + sub_match.args
|
||||
current_route = (
|
||||
""
|
||||
if isinstance(pattern, URLPattern)
|
||||
else str(pattern.pattern)
|
||||
)
|
||||
current_route = '' if isinstance(pattern, URLPattern) else str(pattern.pattern)
|
||||
self._extend_tried(tried, pattern, sub_match.tried)
|
||||
return ResolverMatch(
|
||||
sub_match.func,
|
||||
@@ -680,8 +582,8 @@ class URLResolver:
|
||||
tried,
|
||||
)
|
||||
tried.append([pattern])
|
||||
raise Resolver404({"tried": tried, "path": new_path})
|
||||
raise Resolver404({"path": path})
|
||||
raise Resolver404({'tried': tried, 'path': new_path})
|
||||
raise Resolver404({'path': path})
|
||||
|
||||
@cached_property
|
||||
def urlconf_module(self):
|
||||
@@ -698,26 +600,24 @@ class URLResolver:
|
||||
iter(patterns)
|
||||
except TypeError as e:
|
||||
msg = (
|
||||
"The included URLconf '{name}' does not appear to have "
|
||||
"any patterns in it. If you see the 'urlpatterns' variable "
|
||||
"with valid patterns in the file then the issue is probably "
|
||||
"caused by a circular import."
|
||||
"The included URLconf '{name}' does not appear to have any "
|
||||
"patterns in it. If you see valid patterns in the file then "
|
||||
"the issue is probably caused by a circular import."
|
||||
)
|
||||
raise ImproperlyConfigured(msg.format(name=self.urlconf_name)) from e
|
||||
return patterns
|
||||
|
||||
def resolve_error_handler(self, view_type):
|
||||
callback = getattr(self.urlconf_module, "handler%s" % view_type, None)
|
||||
callback = getattr(self.urlconf_module, 'handler%s' % view_type, None)
|
||||
if not callback:
|
||||
# No handler specified in file; use lazy import, since
|
||||
# django.conf.urls imports this file.
|
||||
from django.conf import urls
|
||||
|
||||
callback = getattr(urls, "handler%s" % view_type)
|
||||
callback = getattr(urls, 'handler%s' % view_type)
|
||||
return get_callable(callback)
|
||||
|
||||
def reverse(self, lookup_view, *args, **kwargs):
|
||||
return self._reverse_with_prefix(lookup_view, "", *args, **kwargs)
|
||||
return self._reverse_with_prefix(lookup_view, '', *args, **kwargs)
|
||||
|
||||
def _reverse_with_prefix(self, lookup_view, _prefix, *args, **kwargs):
|
||||
if args and kwargs:
|
||||
@@ -759,22 +659,16 @@ class URLResolver:
|
||||
# without quoting to build a decoded URL and look for a match.
|
||||
# Then, if we have a match, redo the substitution with quoted
|
||||
# arguments in order to return a properly encoded URL.
|
||||
candidate_pat = _prefix.replace("%", "%%") + result
|
||||
if re.search(
|
||||
"^%s%s" % (re.escape(_prefix), pattern),
|
||||
candidate_pat % text_candidate_subs,
|
||||
):
|
||||
candidate_pat = _prefix.replace('%', '%%') + result
|
||||
if re.search('^%s%s' % (re.escape(_prefix), pattern), candidate_pat % text_candidate_subs):
|
||||
# safe characters from `pchar` definition of RFC 3986
|
||||
url = quote(
|
||||
candidate_pat % text_candidate_subs,
|
||||
safe=RFC3986_SUBDELIMS + "/~:@",
|
||||
)
|
||||
url = quote(candidate_pat % text_candidate_subs, safe=RFC3986_SUBDELIMS + '/~:@')
|
||||
# Don't allow construction of scheme relative urls.
|
||||
return escape_leading_slashes(url)
|
||||
# lookup_view can be URL name or callable, but callables are not
|
||||
# friendly in error messages.
|
||||
m = getattr(lookup_view, "__module__", None)
|
||||
n = getattr(lookup_view, "__name__", None)
|
||||
m = getattr(lookup_view, '__module__', None)
|
||||
n = getattr(lookup_view, '__name__', None)
|
||||
if m is not None and n is not None:
|
||||
lookup_view_s = "%s.%s" % (m, n)
|
||||
else:
|
||||
@@ -788,15 +682,13 @@ class URLResolver:
|
||||
arg_msg = "keyword arguments '%s'" % kwargs
|
||||
else:
|
||||
arg_msg = "no arguments"
|
||||
msg = "Reverse for '%s' with %s not found. %d pattern(s) tried: %s" % (
|
||||
lookup_view_s,
|
||||
arg_msg,
|
||||
len(patterns),
|
||||
patterns,
|
||||
msg = (
|
||||
"Reverse for '%s' with %s not found. %d pattern(s) tried: %s" %
|
||||
(lookup_view_s, arg_msg, len(patterns), patterns)
|
||||
)
|
||||
else:
|
||||
msg = (
|
||||
"Reverse for '%(view)s' not found. '%(view)s' is not "
|
||||
"a valid view function or pattern name." % {"view": lookup_view_s}
|
||||
"a valid view function or pattern name." % {'view': lookup_view_s}
|
||||
)
|
||||
raise NoReverseMatch(msg)
|
||||
|
||||
Reference in New Issue
Block a user