标签:
因为看URL,所以跟到了urlresolvers.py
regex是正则表达式
view
kwargs
name 就是那个 name=‘blog‘
prefix
1 class RegexURLResolver(LocaleRegexProvider): 2 def __init__(self, regex, urlconf_name, default_kwargs=None, app_name=None, namespace=None): 3 LocaleRegexProvider.__init__(self, regex) 4 # urlconf_name is a string representing the module containing URLconfs. 5 self.urlconf_name = urlconf_name 6 if not isinstance(urlconf_name, six.string_types): 7 self._urlconf_module = self.urlconf_name 8 self.callback = None 9 self.default_kwargs = default_kwargs or {} 10 self.namespace = namespace 11 self.app_name = app_name 12 self._reverse_dict = {} 13 self._namespace_dict = {} 14 self._app_dict = {} 15 16 def __repr__(self): 17 if isinstance(self.urlconf_name, list) and len(self.urlconf_name): 18 # Don‘t bother to output the whole list, it can be huge 19 urlconf_repr = ‘<%s list>‘ % self.urlconf_name[0].__class__.__name__ 20 else: 21 urlconf_repr = repr(self.urlconf_name) 22 return str(‘<%s %s (%s:%s) %s>‘) % ( 23 self.__class__.__name__, urlconf_repr, self.app_name, 24 self.namespace, self.regex.pattern) 25 26 def _populate(self): 27 lookups = MultiValueDict() 28 namespaces = {} 29 apps = {} 30 language_code = get_language() 31 for pattern in reversed(self.url_patterns): 32 p_pattern = pattern.regex.pattern 33 if p_pattern.startswith(‘^‘): 34 p_pattern = p_pattern[1:] 35 if isinstance(pattern, RegexURLResolver): 36 if pattern.namespace: 37 namespaces[pattern.namespace] = (p_pattern, pattern) 38 if pattern.app_name: 39 apps.setdefault(pattern.app_name, []).append(pattern.namespace) 40 else: 41 parent = normalize(pattern.regex.pattern) 42 for name in pattern.reverse_dict: 43 for matches, pat, defaults in pattern.reverse_dict.getlist(name): 44 new_matches = [] 45 for piece, p_args in parent: 46 new_matches.extend([(piece + suffix, p_args + args) for (suffix, args) in matches]) 47 lookups.appendlist(name, (new_matches, p_pattern + pat, dict(defaults, **pattern.default_kwargs))) 48 for namespace, (prefix, sub_pattern) in pattern.namespace_dict.items(): 49 namespaces[namespace] = (p_pattern + prefix, sub_pattern) 50 for app_name, namespace_list in pattern.app_dict.items(): 51 apps.setdefault(app_name, []).extend(namespace_list) 52 else: 53 bits = normalize(p_pattern) 54 lookups.appendlist(pattern.callback, (bits, p_pattern, pattern.default_args)) 55 if pattern.name is not None: 56 lookups.appendlist(pattern.name, (bits, p_pattern, pattern.default_args)) 57 self._reverse_dict[language_code] = lookups 58 self._namespace_dict[language_code] = namespaces 59 self._app_dict[language_code] = apps 60 61 @property 62 def reverse_dict(self): 63 language_code = get_language() 64 if language_code not in self._reverse_dict: 65 self._populate() 66 return self._reverse_dict[language_code] 67 68 @property 69 def namespace_dict(self): 70 language_code = get_language() 71 if language_code not in self._namespace_dict: 72 self._populate() 73 return self._namespace_dict[language_code] 74 75 @property 76 def app_dict(self): 77 language_code = get_language() 78 if language_code not in self._app_dict: 79 self._populate() 80 return self._app_dict[language_code] 81 82 def resolve(self, path): 83 tried = [] 84 match = self.regex.search(path) 85 if match: 86 new_path = path[match.end():] 87 for pattern in self.url_patterns: 88 try: 89 sub_match = pattern.resolve(new_path) 90 except Resolver404 as e: 91 sub_tried = e.args[0].get(‘tried‘) 92 if sub_tried is not None: 93 tried.extend([[pattern] + t for t in sub_tried]) 94 else: 95 tried.append([pattern]) 96 else: 97 if sub_match: 98 sub_match_dict = dict(match.groupdict(), **self.default_kwargs) 99 sub_match_dict.update(sub_match.kwargs) 100 return ResolverMatch(sub_match.func, sub_match.args, sub_match_dict, sub_match.url_name, self.app_name or sub_match.app_name, [self.namespace] + sub_match.namespaces) 101 tried.append([pattern]) 102 raise Resolver404({‘tried‘: tried, ‘path‘: new_path}) 103 raise Resolver404({‘path‘ : path}) 104 105 @property 106 def urlconf_module(self): 107 try: 108 return self._urlconf_module 109 except AttributeError: 110 self._urlconf_module = import_module(self.urlconf_name) 111 return self._urlconf_module 112 113 @property 114 def url_patterns(self): 115 patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module) 116 try: 117 iter(patterns) 118 except TypeError: 119 raise ImproperlyConfigured("The included urlconf %s doesn‘t have any patterns in it" % self.urlconf_name) 120 return patterns 121 122 def _resolve_special(self, view_type): 123 callback = getattr(self.urlconf_module, ‘handler%s‘ % view_type, None) 124 if not callback: 125 # No handler specified in file; use default 126 # Lazy import, since django.urls imports this file 127 from django.conf import urls 128 callback = getattr(urls, ‘handler%s‘ % view_type) 129 return get_callable(callback), {} 130 131 def resolve403(self): 132 return self._resolve_special(‘403‘) 133 134 def resolve404(self): 135 return self._resolve_special(‘404‘) 136 137 def resolve500(self): 138 return self._resolve_special(‘500‘) 139 140 def reverse(self, lookup_view, *args, **kwargs): 141 return self._reverse_with_prefix(lookup_view, ‘‘, *args, **kwargs) 142 143 def _reverse_with_prefix(self, lookup_view, _prefix, *args, **kwargs): 144 if args and kwargs: 145 raise ValueError("Don‘t mix *args and **kwargs in call to reverse()!") 146 try: 147 lookup_view = get_callable(lookup_view, True) 148 except (ImportError, AttributeError) as e: 149 raise NoReverseMatch("Error importing ‘%s‘: %s." % (lookup_view, e)) 150 possibilities = self.reverse_dict.getlist(lookup_view) 151 152 prefix_norm, prefix_args = normalize(urlquote(_prefix))[0] 153 for possibility, pattern, defaults in possibilities: 154 for result, params in possibility: 155 if args: 156 if len(args) != len(params) + len(prefix_args): 157 continue 158 unicode_args = [force_text(val) for val in args] 159 candidate = (prefix_norm + result) % dict(zip(prefix_args + params, unicode_args)) 160 else: 161 if set(kwargs.keys()) | set(defaults.keys()) != set(params) | set(defaults.keys()) | set(prefix_args): 162 continue 163 matches = True 164 for k, v in defaults.items(): 165 if kwargs.get(k, v) != v: 166 matches = False 167 break 168 if not matches: 169 continue 170 unicode_kwargs = dict([(k, force_text(v)) for (k, v) in kwargs.items()]) 171 candidate = (prefix_norm.replace(‘%‘, ‘%%‘) + result) % unicode_kwargs 172 if re.search(‘^%s%s‘ % (prefix_norm, pattern), candidate, re.UNICODE): 173 return candidate 174 # lookup_view can be URL label, or dotted path, or callable, Any of 175 # these can be passed in at the top, but callables are not friendly in 176 # error messages. 177 m = getattr(lookup_view, ‘__module__‘, None) 178 n = getattr(lookup_view, ‘__name__‘, None) 179 if m is not None and n is not None: 180 lookup_view_s = "%s.%s" % (m, n) 181 else: 182 lookup_view_s = lookup_view 183 raise NoReverseMatch("Reverse for ‘%s‘ with arguments ‘%s‘ and keyword " 184 "arguments ‘%s‘ not found." % (lookup_view_s, args, kwargs))
标签:
原文地址:http://www.cnblogs.com/IDomyself/p/4786812.html