def register_views(self, app, ar): umap = defaultdict(list) # url -> [(URL, view)] for view in app.get_views(): if hasattr(view, "url"): for u in self.view_urls(view): umap[u.url] += [(u, view)] for url in umap: mm = {} names = set() for u, v in umap[url]: for m in u.method: mm[m] = v if getattr(v, "menu", None): self.register_app_menu(app, v) if u.name: names.add(u.name) sv = self.site_view(app, mm) # Django 1.4 workaround u_name = u.name if u_name and u_name.startswith("admin:"): if "%" in u_name: u_name = u_name % (app.module, app.app) url = "^../%s/%s/%s" % (app.module, app.app, u.url[1:]) self.admin_patterns += [ RegexURLPattern(url, sv, name=u_name.split(":", 1)[1]) ] u_name = u_name.rsplit("_", 1)[1] ar += [RegexURLPattern(u.url, sv, name=u_name)] for n in names: self.register_named_view(app.module, app.app, n, sv)
def decorate_pattern(urlpattern): callback = urlpattern.callback for decorator in reversed(decorators): callback = decorator(callback) return RegexURLPattern(urlpattern.regex.pattern, callback, urlpattern.default_args, urlpattern.name)
def recurse_patterns(path, pattern_list, page_id, default_args=None): """ Recurse over a list of to-be-hooked patterns for a given path prefix """ newpatterns = [] for pattern in pattern_list: app_pat = pattern.regex.pattern # make sure we don't get patterns that start with more than one '^'! app_pat = app_pat.lstrip('^') path = path.lstrip('^') regex = r'^%s%s' % (path, app_pat) if isinstance(pattern, RegexURLResolver): # this is an 'include', recurse! resolver = RegexURLResolver(regex, 'cms_appresolver', pattern.default_kwargs, pattern.app_name, pattern.namespace) resolver.page_id = page_id # include default_args args = pattern.default_kwargs if default_args: args.update(default_args) # see lines 243 and 236 of urlresolvers.py to understand the next line resolver._urlconf_module = recurse_patterns( regex, pattern.url_patterns, page_id, args) else: # Re-do the RegexURLPattern with the new regular expression args = pattern.default_args if default_args: args.update(default_args) resolver = RegexURLPattern(regex, pattern.callback, args, pattern.name) resolver.page_id = page_id newpatterns.append(resolver) return newpatterns
def recurse_patterns(path, pattern_list, page_id): """ Recurse over a list of to-be-hooked patterns for a given path prefix """ newpatterns = [] for pattern in pattern_list: app_pat = pattern.regex.pattern if app_pat.startswith('^'): app_pat = app_pat[1:] regex = r'^%s%s' % (path, app_pat) if isinstance(pattern, RegexURLResolver): # this is an 'include', recurse! resolver = RegexURLResolver(regex, 'cms_appresolver', pattern.default_kwargs, pattern.app_name, pattern.namespace) resolver.page_id = page_id # see lines 243 and 236 of urlresolvers.py to understand the next line resolver._urlconf_module = recurse_patterns( regex, pattern.url_patterns, page_id) else: # Re-do the RegexURLPattern with the new regular expression resolver = RegexURLPattern(regex, pattern.callback, pattern.default_args, pattern.name) resolver.page_id = page_id newpatterns.append(resolver) return newpatterns
def test_populate_urlconf_no_ssl_urls(self): class URLConf: urlpatterns = [] sub_urlconf = URLConf() sub_urlconf.urlpatterns = [ RegexURLPattern('', logout_view), ] root_urlconf = URLConf() root_urlconf.urlpatterns = [ RegexURLPattern('', login_view), RegexURLResolver('', sub_urlconf), ] self.mw._protected_urls = [] self.mw._walk_module(root_urlconf) self.assertIn(login_view, self.mw._protected_urls) self.assertIn(logout_view, self.mw._protected_urls)
def get_proxy_resolver(urlconf, default_view): from django.conf import settings set_urlconf(urlconf) resolver = get_resolver(urlconf) callback = import_string(default_view) if callback not in resolver.reverse_dict: pattern = RegexURLPattern(r'', callback) resolver.url_patterns.append(pattern) return resolver
def ajax_url(regex, view, ajax_name, default=None, group=None, kwargs=None): if isinstance(view, (list, tuple)): urlconf_module, app_name, namespace = view AjaxTracker.Instance().add_ajax_url(regex, ajax_name, default, group) return RegexURLResolver(regex, urlconf_module, kwargs, app_name=app_name, namespace=namespace) if isinstance(view, six.string_types): raise ImproperlyConfigured('Invalid view specified (%s). Are you passing the callable?' % view) AjaxTracker.Instance().add_ajax_url(regex, ajax_name, default, group) return RegexURLPattern(regex, view, kwargs, ajax_name)
def lr_patt(urlpatterns, exp_name=[]): u = [] for _url in urlpatterns: if _url.name not in exp_name: s = RegexURLPattern(_url.regex.pattern, login_required(_url.callback), name=_url.name) u.append(s) else: u.append(_url) return u
def inherit(mod_name, patterns, cbv=True): """ Inherit class based view class or feed class """ pattern_list = [] for t in patterns: class_name = t.callback.__name__ if cbv else t.callback.__class__.__name__ callback = getattr(import_module(mod_name), class_name) callback = callback.as_view() if cbv else callback() pattern_list.append(RegexURLPattern(t._regex, callback, t.default_args, t.name)) return pattern_list
def url(regex, view, kwargs=None, name=None, prefix=''): if isinstance(view, (list, tuple)): # For include(...) processing. urlconf_module, app_name, namespace = view return RegexURLResolver(regex, urlconf_module, kwargs, app_name=app_name, namespace=namespace) else: if isinstance(view, six.string_types): if not view: raise ImproperlyConfigured('Empty URL pattern view name not permitted (for pattern %r)' % regex) if prefix: view = prefix + '.' + view return RegexURLPattern(regex, view, kwargs, name)
def get_urls(self): from django.core.urlresolvers import RegexURLPattern urlpatterns = super(AdminSite, self).get_urls() # copy and replace the contenttypes.shortcut pattern shortcut_pattern, index = [(p, i) for i, p in enumerate(urlpatterns) if p.callback and p.callback.func_name == 'shortcut'][0] callback = copy_func(shortcut_pattern.callback) callback.func_globals['ContentType'] = ContentType urlpatterns[index] = RegexURLPattern(shortcut_pattern.regex, callback, default_args=shortcut_pattern.default_args, name = 'shortcut') return urlpatterns
def get_urls(self): def wrap(view): def wrapper(*args, **kwargs): return self.admin_site.admin_view(view)(*args, **kwargs) return update_wrapper(wrapper, view) return [ # they are already prefixed RegexURLPattern(str(url.regex.pattern), wrap( url.callback), url.default_args, url.name) if isinstance( url, RegexURLPattern) else url for url in urls ]
def url(regex, view, kwargs=None, name=None, prefix=''): if type(view) == list: # For include(...) processing. return RegexURLResolver(regex, view[0], kwargs) else: if isinstance(view, str): if not view: raise ImproperlyConfigured( 'Empty URL pattern view name not permitted (for pattern %r)' % regex) if prefix: view = prefix + '.' + view return RegexURLPattern(regex, view, kwargs, name)
def add_conf_to_pattern(self, pattern, conf, bases): """ Coalesces an Application's configuration with the views in its urlconf. Takes a RegexURLPattern or RegexURLResolver, a conf object and a tuple of extra base classes to inherit from. Returns an object of the same type as its first argument with callbacks replaced with new views using conf and bases. """ # Don't import at module scope as this module will be imported from a # settings file. from molly.utils.views import BaseView if isinstance(pattern, RegexURLResolver): # Recurse through the patterns patterns = [] for subpattern in pattern.url_patterns: patterns.append( self.add_conf_to_pattern(subpattern, conf, bases)) # Create a new RegexURLResolver with the new patterns return RegexURLResolver( pattern.regex.pattern, # The regex pattern string patterns, pattern.default_kwargs, pattern.app_name, pattern.namespace) elif isinstance(pattern, RegexURLPattern): # Get the callback and make sure it derives BaseView callback = pattern.callback if not issubclass(callback, BaseView): return callback if bases: # Create a new callback with the extra bases callback = type(callback.__name__ + 'Extended', (callback, ) + bases, {}) callback.__module__ = pattern.callback.__module__ # Instantiate the callback with the conf object callback = callback(conf) # Transplant this new callback into a new RegexURLPattern, keeping # the same regex, default_args and name. return RegexURLPattern(pattern.regex.pattern, callback, pattern.default_args, pattern.name) else: raise TypeError( "Expected RegexURLResolver or RegexURLPattern instance, got %r." % type(pattern))
def patterns(prefix, *tuples): pattern_list = [] for t in tuples: regex, view_or_include = t[:2] default_kwargs = t[2:] if type(view_or_include) == list: pattern_list.append( RegexURLResolver(regex, view_or_include[0], *default_kwargs)) else: pattern_list.append( RegexURLPattern( regex, prefix and (prefix + '.' + view_or_include) or view_or_include, *default_kwargs)) return pattern_list
def url(regex, view, kwargs=None, name=None): if isinstance(view, (list, tuple)): # For include(...) processing. urlconf_module, app_name, namespace = view return RegexURLResolver(regex, urlconf_module, kwargs, app_name=app_name, namespace=namespace) elif callable(view): return RegexURLPattern(regex, view, kwargs, name) else: raise TypeError( 'view must be a callable or a list/tuple in the case of include().' )
def _assert_dispatchable_url(self, name, user): backend = Backend() section = backend.get_section_by_class(MediaBackendSection) subsection = section.get_section_by_class(ImageBackendSection) def callback(self): return HttpResponse('Foo') regexUrl = RegexURLPattern(r'/', callback, name=name) backend.dispatchable_url(regexUrl, section, subsection) factory = RequestFactory() request = factory.get('/') request.user = user return regexUrl.callback(request)
def patterns_insert(prefix, pattern_list, index, tuples): from django.core.urlresolvers import RegexURLPattern, RegexURLResolver pattern_list = pattern_list if ( misc.isList(pattern_list)) else [pattern_list] for t in tuples: regex, view_or_include = t[:2] default_kwargs = t[2:] if type(view_or_include) == list: pattern_list.append( RegexURLResolver(regex, view_or_include[0], *default_kwargs)) else: pattern_list.append( RegexURLPattern( regex, prefix and (prefix + '.' + view_or_include) or view_or_include, *default_kwargs)) return pattern_list
def decorate_pattern(self, pattern): if isinstance(pattern, RegexURLResolver): regex = pattern.regex.pattern urlconf_module = pattern.urlconf_name default_kwargs = pattern.default_kwargs namespace = pattern.namespace app_name = pattern.app_name urlconf = DecoratedPatterns(urlconf_module, self.decorators) decorated = RegexURLResolver(regex, urlconf, default_kwargs, app_name, namespace) else: callback = pattern.callback for decorator in reversed(self.decorators): callback = decorator(callback) decorated = RegexURLPattern(pattern.regex.pattern, callback, pattern.default_args, pattern.name) return decorated
def url(regex, view, kwargs=None, name=None, prefix=''): if isinstance(view, (list, tuple)): # For include(...) processing. urlconf_module, app_name, namespace = view return RegexURLResolver(regex, urlconf_module, kwargs, app_name=app_name, namespace=namespace) else: if isinstance(view, six.string_types): warnings.warn( 'Support for string view arguments to url() is deprecated and ' 'will be removed in Django 2.0 (got %s). Pass the callable ' 'instead.' % view, RemovedInDjango20Warning, stacklevel=2 ) if not view: raise ImproperlyConfigured('Empty URL pattern view name not permitted (for pattern %r)' % regex) if prefix: view = prefix + '.' + view return RegexURLPattern(regex, view, kwargs, name)
def urlpatterns(self, prefix, pattern_dict): patterns = self.patterns(prefix, pattern_dict) urlpatterns = [] for p in patterns: urlpatterns.append(RegexURLPattern(*p)) return urlpatterns
def __new__(cls, class_name, bases, attrs): module = attrs['__module__'].split(".", 2)[2].replace(".", "/") # attrs['__module__'].rsplit( ".", 1 )[-1] application = CmsMetaclass.__module__.split(".", 1)[0] cls = type.__new__(cls, class_name, bases, attrs) cls.application = application cls.module = module class_items = {} for parent in bases: class_items.update(parent.__dict__) class_items.update(attrs) for name, view in class_items.iteritems(): if type(view) is not FunctionType: continue if name.startswith("site_"): name = name.replace("site_", "") config = Config() config.name = name template = getattr(view, "template", None) if not template: template = "%s/%s.html" % (module, name) template = "%s/%s" % (application, template) config.template = template args, _, _, defaults = getargspec(view) defaults = defaults or [] defaults_args = dict(zip(list(args[-len(defaults):]), defaults)) args = getargspec(view).args args.remove("self") r = [] if hasattr(view, "url"): regex = getattr(view, "url") else: regex = "{application}/{module}/{method}/{{r}}$".format(application=application, module=module, method=name) view_name = "{application}_{module}_{method}".format(application=application, module=module, method=name) config.urlname = view_name urls.add(module, name, view_name) callback = CmsMetaclass.get_view(cls, config, view.__name__) for a in args: if a in defaults_args: url = RegexURLPattern(regex=regex.format(r="".join(r)), callback=callback, name=view_name) urlpatterns.append(url) r.append("(?P<{name}>[-\w]+)/".format(name=a)) if r: url = RegexURLPattern(regex=regex.format(r="".join(r)), callback=callback, name=view_name) else: url = RegexURLPattern(regex=regex.format(r="".join(r)), callback=callback, name=view_name) urlpatterns.append(url) menu.add_view(class_items, view, view_name) # fun = cls.get_view( "get_list", {"aa":"aa"} ) cls.urls = getattr(urls, module) cls.all_urls = urls registry.append(cls) return cls
for t in args: if isinstance(t, (list, tuple)): t = url(prefix=prefix, *t) 自动转换 elif isinstance(t, RegexURLPattern): t.add_prefix(prefix) pattern_list.append(t) # 返回 RegexURLResolver 或者 RegexURLPattern 对象的列表 return pattern_list # url 函数 def url(regex, view, kwargs=None, name=None, prefix=''): if isinstance(view, (list,tuple)): 如果是 list 或者 tuple # For include(...) processing. 处理包含 include(...) urlconf_module, app_name, namespace = view # 此处返回 RegexURLResolver, 区分下面返回 RegexURLPattern return RegexURLResolver(regex, urlconf_module, kwargs, app_name=app_name, namespace=namespace) else: if isinstance(view, six.string_types): if not view: raise ImproperlyConfigured('Empty URL pattern view name not permitted (for pattern %r)' % regex) if prefix: view = prefix + '.' + view # 返回 RegexURLPattern 的对象 return RegexURLPattern(regex, view, kwargs, name) # 从上面可以获知, url 会返回 RegexURLResolver 或者 RegexURLPattern 对象
from django.core.urlresolvers import RegexURLPattern from rest_framework.routers import DefaultRouter from archiveit.wasapi.views import WebdataQueryViewSet, JobsViewSet, update_result_file_state, JobResultViewSet router = DefaultRouter(trailing_slash=False) router.register(r'webdata', WebdataQueryViewSet) router.register(r'jobs/(?P<jobid>\d+)/result', JobResultViewSet) router.register(r'jobs', JobsViewSet) router.urls.append( RegexURLPattern(r'^update_result_file_state/(?P<filename>.*)', update_result_file_state)) urlpatterns = router.urls
def get_urls(self, *args, **kwds): urls = super(TrackerAdmin, self).get_urls(*args, **kwds) urls.insert(0, RegexURLPattern(r'sync_all$', sync_all)) return urls
except AttributeError, e: logger.debug("Could not find any urlpatterns for '%s'" % app) return None for app in settings.USER_APPS: app_prefix = r'^%s/' % app urls = load_urls_for_app(app) if urls: # It could be that the app has no 'home' view, so we simply use # first view in the list has_home = len(filter(lambda url: url.name is 'home', urls)) if not has_home: first_url = urls[0] home_url = RegexURLPattern( first_url.regex.pattern, first_url.callback, first_url.default_args, 'home' ) urls.insert(0, home_url) # In case the user didn't add any urlpattern at the root, # we add one for them. This one will never be hit if the user # defined one. urls.append(url(r'^$', redirect_to_home(app))) # We're going to add some catch-all routes, namely: # /<app>/flashtimeline -> /<locale>/app/<app>/search # /<app>/search -> /<locale>/app/<app>/search # /<app>/<template_name> -> will render that template in that app # Again, if the user has defined anything that matches these, then the # catch-all ones will never be hit.
def url_annotator(view): view.pattern = RegexURLPattern(pattern, view, extra, name) return view