def reverse_subdomain(name, args=(), kwargs=None): if args and kwargs: raise ValueError("Don't mix *args and **kwargs in call to reverse()!") if kwargs is None: kwargs = {} try: subdomain = settings.SUBDOMAINS[name] except KeyError: raise NoReverseMatch("No subdomain called %s exists" % name) unicode_args = [force_unicode(x) for x in args] unicode_kwargs = dict([(k, force_unicode(v)) for (k, v) in kwargs.items()]) for result, params in normalize(subdomain['regex']): if args: if len(args) != len(params): continue candidate = result % dict(zip(params, unicode_args)) else: if set(kwargs.keys()) != set(params): continue candidate = result % unicode_kwargs if re.match(subdomain['regex'], candidate, re.UNICODE): return candidate raise NoReverseMatch( "Reverse subdomain for '%s' with arguments '%s' and keyword arguments " "'%s' not found." % (name, args, kwargs))
def urls_by_namespace(namespace, urlconf=None, args=None, kwargs=None, prefix=None, current_app=None): """ Return a dictionary containing the name together with the URL of all configured URLs specified for this namespace. """ if urlconf is None: urlconf = get_urlconf() resolver = get_resolver(urlconf) args = args or [] kwargs = kwargs or {} if prefix is None: prefix = get_script_prefix() if not namespace or not isinstance(namespace, basestring): raise AttributeError('Attribute namespace must be of type string') path = namespace.split(':') path.reverse() resolved_path = [] ns_pattern = '' while path: ns = path.pop() # Lookup the name to see if it could be an app identifier try: app_list = resolver.app_dict[ns] # Yes! Path part matches an app in the current Resolver if current_app and current_app in app_list: # If we are reversing for a particular app, # use that namespace ns = current_app elif ns not in app_list: # The name isn't shared by one of the instances # (i.e., the default) so just pick the first instance # as the default. ns = app_list[0] except KeyError: pass try: extra, resolver = resolver.namespace_dict[ns] resolved_path.append(ns) ns_pattern = ns_pattern + extra except KeyError, key: if resolved_path: raise NoReverseMatch( "%s is not a registered namespace inside '%s'" % (key, ':'.join(resolved_path))) else: raise NoReverseMatch("%s is not a registered namespace" % key)
def page_reverse(slug): page = Page.objects.filter(slug=slug).first() if not page: raise NoReverseMatch("Page {!r} not found.".format(slug)) return page.get_absolute_url()
def get_url(self, obj, view_name, request, format): """ Given an object, return the URL that hyperlinks to the object. May raise a `NoReverseMatch` if the `view_name` and `lookup_field` attributes are not configured to correctly match the URL conf. """ lookup_field = getattr(obj, self.lookup_field) kwargs = {self.lookup_field: lookup_field} try: return reverse(view_name, kwargs=kwargs, request=request, format=format) except NoReverseMatch: pass if self.pk_url_kwarg != 'pk': # Only try pk lookup if it has been explicitly set. # Otherwise, the default `lookup_field = 'pk'` has us covered. kwargs = {self.pk_url_kwarg: obj.pk} try: return reverse(view_name, kwargs=kwargs, request=request, format=format) except NoReverseMatch: pass slug = getattr(obj, self.slug_field, None) if slug: # Only use slug lookup if a slug field exists on the model kwargs = {self.slug_url_kwarg: slug} try: return reverse(view_name, kwargs=kwargs, request=request, format=format) except NoReverseMatch: pass raise NoReverseMatch()
def _reverse_with_prefix(self, lookup_view, _prefix, *args, **kwargs): if args and kwargs: raise ValueError("Don't mix *args and **kwargs in call to reverse()!") try: lookup_view = get_callable(lookup_view, True) except (ImportError, AttributeError), e: raise NoReverseMatch("Error importing '%s': %s." % (lookup_view, e))
def test_get_page_url_view_sub(self, mock_reverse): mock_reverse.side_effect = [NoReverseMatch(), "/some_nice_url"] url = bootstrap_pagination.get_page_url( page_num=42, current_app='the_current_app', url_view_name='the_view', url_extra_args=["arg1"], url_extra_kwargs={"kwarg": "yes"}, url_param_name='page', url_get_params=django.http.QueryDict(""), url_anchor="derp") self.assertEqual(url, '/some_nice_url#derp') if django.VERSION < (1, 9, 0): sep = '.' else: sep = ':' mock_reverse.assert_called_with('tests' + sep + 'the_view', args=['arg1'], current_app='the_current_app', kwargs={ 'kwarg': 'yes', 'page': 42 })
def admin_link(self, model, method='change', obj=None): ct = ContentType.objects.get_for_model(model) bits = (ct.app_label, ct.model, method) args = (obj.pk, ) if obj else () perm = '%s.%s_%s' % (ct.app_label, method, ct.model) if self.request.user.has_perm(perm): return reverse('admin:%s_%s_%s' % bits, args=args) raise NoReverseMatch("No permission")
def reverse_for_language(viewname, lang, urlconf=None, args=None, kwargs=None, prefix=None, current_app=None): # Based on code in Django 1.1.1 in reverse and RegexURLResolver.reverse # in django.core.urlresolvers. args = args or [] kwargs = kwargs or {} if prefix is None: prefix = get_script_prefix() resolver = get_resolver(urlconf, lang) if not isinstance(viewname, basestring): view = viewname else: parts = viewname.split(':') parts.reverse() view = parts[0] path = parts[1:] resolved_path = [] while path: ns = path.pop() # Lookup the name to see if it could be an app identifier try: app_list = resolver.app_dict[ns] # Yes! Path part matches an app in the current Resolver if current_app and current_app in app_list: # If we are reversing for a particular app, use that namespace ns = current_app elif ns not in app_list: # The name isn't shared by one of the instances (i.e., the default) # so just pick the first instance as the default. ns = app_list[0] except KeyError: pass try: extra, resolver = resolver.namespace_dict[ns] resolved_path.append(ns) prefix = prefix + extra except KeyError, key: if resolved_path: raise NoReverseMatch("%s is not a registered namespace inside '%s'" % (key, ':'.join(resolved_path))) else: raise NoReverseMatch("%s is not a registered namespace" % key)
def get_redirect_path(setting_var, value): try: path = reverse(value) except NoReverseMatch: raise NoReverseMatch("{setting_var}: Improperly configured in \ Django Settings.\n`{value}` is not a valid URL name.\ \n\nTo fix url pattern name, read about `reverse` here: \ \nhttps://docs.djangoproject.com/en/dev/ref/urlresolvers/#reverse".format( setting_var=setting_var, value=value)) return path
def reverse_path(subdomain, view, args=(), kwargs=None): if kwargs is None: kwargs = {} try: urlconf = settings.SUBDOMAINS[subdomain]['urlconf'] except KeyError: raise NoReverseMatch("No subdomain called %s exists" % subdomain) return reverse(view, args=args, kwargs=kwargs, urlconf=urlconf)
def get_host(name=None): if name is None: try: name = settings.DEFAULT_HOST except AttributeError: raise ImproperlyConfigured("Missing DEFAULT_HOST setting") for host in get_host_patterns(): if host.name == name: return host raise NoReverseMatch("No host called '%s' exists" % name)
def reverse_host(host, args=None, kwargs=None): """ Given the host name and the appropriate parameters, reverses the host, e.g.:: >>> from django.conf import settings >>> settings.ROOT_HOSTCONF = 'mysite.hosts' >>> settings.PARENT_HOST = 'example.com' >>> from django_hosts.resolvers import reverse_host >>> reverse_host('with_username', args=('jezdez',)) 'jezdez.example.com' :param name: the name of the host as specified in the hostconf :param args: the host arguments to use to find a matching entry in the hostconf :param kwargs: similar to args but key value arguments :raises django.core.urlresolvers.NoReverseMatch: if no host matches :rtype: reversed hostname """ if args and kwargs: raise ValueError("Don't mix *args and **kwargs in call to reverse()!") args = args or () kwargs = kwargs or {} if not isinstance(host, host_cls): host = get_host(host) unicode_args = [force_text(x) for x in args] unicode_kwargs = dict( ((k, force_text(v)) for (k, v) in six.iteritems(kwargs))) for result, params in normalize(host.regex): if args: if len(args) != len(params): continue candidate = result % dict(zip(params, unicode_args)) else: if set(kwargs.keys()) != set(params): continue candidate = result % unicode_kwargs if re.match(host.regex, candidate, re.UNICODE): # pragma: no cover parent_host = getattr(settings, 'PARENT_HOST', '').lstrip('.') if parent_host: # only add the parent host when needed (aka www-less domain) if candidate and candidate != parent_host: candidate = '%s.%s' % (candidate, parent_host) else: candidate = parent_host return candidate raise NoReverseMatch("Reverse host for '%s' with arguments '%s' " "and keyword arguments '%s' not found." % (host.name, args, kwargs))
def render(self, context): args = [arg.resolve(context) for arg in self.args] kwargs = dict([(smart_text(k, 'ascii'), v.resolve(context)) for k, v in self.kwargs.items()]) label = self.label.resolve(context) if not label: raise NoReverseMatch("'navitem' requires a non-empty first argument.") viewname = self.viewname.resolve(context) if not viewname: raise NoReverseMatch("'navitem' requires a non-empty second argument.") url = reverse(viewname, args=args, kwargs=kwargs, current_app=context.current_app) path = context['request'].path link = '<a href="%s">%s</a>' % (url, label) if url in path or url == path: return '<li class="active">%s</li>' % (link) return '<li>%s</li>' % (link)
class BRegexURLResolver(RegexURLResolver): """ from django/core/urlresolvers.py modified as noted """ def _reverse_with_prefix(self, lookup_view, _prefix, *args, **kwargs): if args and kwargs: raise ValueError("Don't mix *args and **kwargs in call to reverse()!") try: lookup_view = get_callable(lookup_view, True) except (ImportError, AttributeError), e: raise NoReverseMatch("Error importing '%s': %s." % (lookup_view, e)) possibilities = self.reverse_dict.getlist(lookup_view) prefix_norm, prefix_args = normalize(_prefix)[0] for possibility, pattern, defaults in possibilities: for result, params in possibility: if args: # ## START MODS expected_length = len(params) + len(prefix_args) if len(args) < expected_length: continue args = args[:expected_length] # ## END MODS unicode_args = [force_unicode(val) for val in args] candidate = (prefix_norm + result) % dict(zip(prefix_args + params, unicode_args)) else: # ## START MODS if set(params + defaults.keys() + prefix_args) - set(kwargs.keys() + defaults.keys()): continue # ## END MODS matches = True for k, v in defaults.items(): if kwargs.get(k, v) != v: matches = False break if not matches: continue unicode_kwargs = dict([(k, force_unicode(v)) for (k, v) in kwargs.items()]) candidate = (prefix_norm + result) % unicode_kwargs if re.search(u'^%s%s' % (_prefix, pattern), candidate, re.UNICODE): return candidate # lookup_view can be URL label, or dotted path, or callable, Any of # these can be passed in at the top, but callables are not friendly in # error messages. 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: lookup_view_s = lookup_view raise NoReverseMatch("Reverse for '%s' with arguments '%s' and keyword " "arguments '%s' not found." % (lookup_view_s, args, kwargs))
def _find_plugin_reverse(viewname, args, kwargs): plugins = page_type_pool.get_url_pattern_plugins() for plugin in plugins: try: url_end = plugin.get_url_resolver().reverse(viewname, *args, **kwargs) return plugin, url_end except NoReverseMatch: pass else: raise NoReverseMatch("Reverse for application URL '%s' with arguments '%s' and keyword " "arguments '%s' not found." % (viewname, args, kwargs))
def render(self, context): from django.core.urlresolvers import reverse, NoReverseMatch args = [arg.resolve(context) for arg in self.args] kwargs = dict([(smart_text(k, 'ascii'), v.resolve(context)) for k, v in self.kwargs.items()]) view_name = self.view_name.resolve(context) if not view_name: raise NoReverseMatch( "'url' requires a non-empty first argument. " "The syntax changed in Django 1.5, see the docs.") # Try to look up the URL twice: once given the view name, and again # relative to what we guess is the "main" app. If they both fail, # re-raise the NoReverseMatch unless we're using the # {% url ... as var %} construct in which case return nothing. url = '' try: url = reverse(view_name, args=args, kwargs=kwargs, current_app=context.current_app, urlconf=self.urlconf) except NoReverseMatch as e: try: url = reverse(view_name, args=args, kwargs=kwargs, current_app=context.current_app) except NoReverseMatch: if self.urlconf != settings.ROOT_URLCONF: # Re-try to match on the base urlconf instead, and render as an absolute URL. try: host = settings.DEFAULT_HOST host_args, host_kwargs = (), {} return HostURLNode(host, self.view_name, host_args, host_kwargs, self.args, self.original_kwargs, self.asvar).render(context) except: pass if self.asvar is None: # Re-raise the original exception, not the one with # the path relative to the project. This makes a # better error message. raise e if self.asvar: context[self.asvar] = url return '' else: return url
def get_formatted_url(url_name): try: return reverse(url_name) except NoReverseMatch as e: # Url regex pattern has named parameters. Translate these to Javascript sprintf() library format. urlresolver = get_resolver(None) for matches, pat, defaults in urlresolver.reverse_dict.getlist( url_name): for sprintf_url, named_parameters in matches: return '{}{}'.format(get_script_prefix(), sprintf_url) raise NoReverseMatch('Cannot find sprintf formatted url for %s' % url_name)
def get_url(self, obj, view_name, request, format): """ Given an object, return the URL that hyperlinks to the object. May raise a `NoReverseMatch` if the `view_name` and `lookup_field` attributes are not configured to correctly match the URL conf. """ lookup_field = getattr(obj, self.lookup_field) kwargs = {self.lookup_field: lookup_field} try: return reverse(view_name, kwargs=kwargs, request=request, format=format) except NoReverseMatch: pass if self.pk_url_kwarg != "pk": # Only try pk if it has been explicitly set. # Otherwise, the default `lookup_field = "pk"` has us covered. pk = obj.pk kwargs = {self.pk_url_kwarg: pk} try: return reverse(view_name, kwargs=kwargs, request=request, format=format) except NoReverseMatch: pass slug = getattr(obj, self.slug_field, None) if slug is not None: # Only try slug if it corresponds to an attribute on the object. kwargs = {self.slug_url_kwarg: slug} try: ret = reverse(view_name, kwargs=kwargs, request=request, format=format) if self.slug_field == "slug" and self.slug_url_kwarg == "slug": # If the lookup succeeds using the default slug params, # then `slug_field` is being used implicitly, and we # we need to warn about the pending deprecation. msg = ( "Implicit slug field hyperlinked fields are pending deprecation." "You should set `lookup_field=slug` on the HyperlinkedRelatedField." ) warnings.warn(msg, PendingDeprecationWarning, stacklevel=2) return ret except NoReverseMatch: pass raise NoReverseMatch()
def reverse_resource(resource, viewname, args=None, kwargs=None, request=None, format=None, **extra): """ Generate the URL for the view specified as viewname of the object specified as resource. """ kwargs = kwargs or {} parent = resource while parent is not None: if not hasattr(parent, 'get_url_kwarg'): return NoReverseMatch('Cannot get URL kwarg for %s' % resource) kwargs.update({parent.get_url_kwarg(): parent.mnemonic}) parent = parent.parent if hasattr(parent, 'parent') else None rval = reverse(viewname, args, kwargs, request, format, **extra) return rval
def edit_link(object): """ Get object and render link to it admin edit page """ try: link = reverse( 'admin:%s_%s_change' % (object._meta.app_label, object.__class__.__name__.lower()), args=(object.id, )) return link except NoReverseMatch: raise NoReverseMatch("This model hasn't got edit link") except AttributeError: raise ObjectDoesNotExist("No such model")
def reverse(viewname, subdomain=UNSET, scheme=None, args=None, kwargs=None, current_app=None): """ Reverses a URL from the given parameters, in a similar fashion to :meth:`django.core.urlresolvers.reverse`. :param viewname: the name of URL :param subdomain: the subdomain to use for URL reversing :param scheme: the scheme to use when generating the full URL :param args: positional arguments used for URL reversing :param kwargs: named arguments used for URL reversing :param current_app: hint for the currently executing application """ if subdomain is not UNSET: urlconf = settings.SUBDOMAIN_URLCONFS.get(subdomain, settings.ROOT_URLCONF) path = simple_reverse(viewname, urlconf=urlconf, args=args, kwargs=kwargs, current_app=current_app) else: path = None for subdomain, urlconf in settings.SUBDOMAIN_URLCONFS.items(): try: path = simple_reverse(viewname, urlconf=urlconf, args=args, kwargs=kwargs, current_app=current_app) except NoReverseMatch: path = None else: break if not path: raise NoReverseMatch( "Reverse for '%s' with arguments '%s' and keyword " "arguments '%s' not found." % (viewname, args, kwargs)) domain = get_domain() if subdomain is not None: domain = '%s.%s' % (subdomain, domain) return urljoin(domain, path, scheme=scheme)
def model_reverse(viewname, instance, urlconf=None, args=None, kwargs=None, prefix=None, current_app=None): """ Calculates an url from a view name when passing a dictable object (such a Model instance) as parameter. The function will parse the url pattern and attempt to match the instance properties with the urlpattern kwargs. """ matching_pattern = None if urlconf is None: urlconf = get_urlconf() resolver = get_resolver(urlconf) possibilities = [] (namespace, url) = (None, viewname) if ":" in viewname: (namespace, url) = viewname.split(":") for urlpattern in resolver.url_patterns: possibilities.append(urlpattern) if ((not hasattr(urlpattern, 'namespace') and not namespace) or (hasattr(urlpattern, 'namespace') and urlpattern.namespace == namespace)): if hasattr(urlpattern, 'url_patterns'): for subpattern in urlpattern.url_patterns: if subpattern.name == url: matching_pattern = subpattern else: if urlpattern.name == url: matching_pattern = urlpattern try: kwarg_keys = matching_pattern.regex.groupindex.keys() except AttributeError: raise NoReverseMatch("Reverse for '%s' with instance '%s' of class " "'%s' not found. %d pattern(s) tried: %s" % (viewname, instance, instance.__class__, len(possibilities), possibilities)) kwargs = {} for key in kwarg_keys: kwargs[key] = str(getattr(instance, key, None)) return dj_reverse(viewname, urlconf=urlconf, prefix=prefix, current_app=current_app, args=args, kwargs=kwargs)
def render(self, context): from django.core.urlresolvers import reverse, NoReverseMatch args = [arg.resolve(context) for arg in self.args] kwargs = dict([(smart_text(k, 'ascii'), v.resolve(context)) for k, v in self.kwargs.items()]) kwargs['url'] = get_current_account(context['request']).url view_name = self.view_name.resolve(context) if not view_name: raise NoReverseMatch( "'url' requires a non-empty first argument. " "The syntax changed in Django 1.5, see the docs.") # Try to look up the URL twice: once given the view name, and again # relative to what we guess is the "main" app. If they both fail, # re-raise the NoReverseMatch unless we're using the # {% url ... as var %} construct in which case return nothing. url = '' current_app = context['request'].resolver_match.app_name try: url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app) except NoReverseMatch as e: if settings.SETTINGS_MODULE: project_name = settings.SETTINGS_MODULE.split('.')[0] try: url = reverse(project_name + '.' + view_name, args=args, kwargs=kwargs, current_app=current_app) except NoReverseMatch: if self.asvar is None: # Re-raise the original exception, not the one with # the path relative to the project. This makes a # better error message. raise e else: if self.asvar is None: raise e if self.asvar: context[self.asvar] = url return '' else: return url
def get_url(self, obj, view_name, request, format): """ Given an object, return the URL that hyperlinks to the object. May raise a `NoReverseMatch` if the `view_name` and `lookup_field` attributes are not configured to correctly match the URL conf. """ lookup_field = getattr(obj, self.lookup_field) domain_lookup_field = getattr(obj, self.domain_lookup_field) # TODO find out domain_lookup_field kwargs = {self.lookup_field: lookup_field, self.domain_lokup_field: domain_lookup_field} return reverse(view_name, kwargs=kwargs, request=request, format=format) raise NoReverseMatch()
def _find_plugin_reverse(viewname, args, kwargs): from fluent_pages.extensions import page_type_pool plugins = page_type_pool.get_url_pattern_plugins() for plugin in plugins: try: url_end = plugin.get_url_resolver().reverse(viewname, *args, **kwargs) return plugin, url_end except NoReverseMatch: pass else: raise NoReverseMatch( "Reverse for application URL '{0}' with arguments '{1}' and keyword arguments '{2}' not found.\n" "Searched in URLconf and installed page type plugins ({3}) for URLs.".format( viewname, args, kwargs, ', '.join(x.__class__.__name__ for x in page_type_pool.get_plugins()) or "none" ))
def get_url(self, obj, view_name, request, format): """ Given an object, return the URL that hyperlinks to the object. May raise a `NoReverseMatch` if the `view_name` and `lookup_field` attributes are not configured to correctly match the URL conf. """ # Handle unsaved object case if obj.pk is None: return None # Default to the parent model name if self.lookup_prefix is None: self.lookup_prefix = self.parent.opts.model.__name__.lower() if self.lookup_prefix: lookup_key = '%s_%s' % (self.lookup_prefix, self.lookup_field) # `lookup_prefix` explicitly passed as an empty string else: lookup_key = self.lookup_field kwargs = {lookup_key: getattr(obj, self.lookup_field)} try: return reverse(view_name, kwargs=kwargs, request=request, format=format) except NoReverseMatch: pass slug = getattr(obj, self.slug_field, None) if slug: # Only use slug lookup if a slug field exists on the model kwargs = {self.slug_url_kwarg: slug} try: return reverse(view_name, kwargs=kwargs, request=request, format=format) except NoReverseMatch: pass raise NoReverseMatch()
def parse_url(lookup_view): if not lookup_view: raise ValueError("No lookup_view") url = None try: url = reverse_with_params(viewname=lookup_view['viewname'], args=lookup_view['args'], query_string=lookup_view['query_string']) except KeyError: # assume we've been passed a url try: resolve(lookup_view) url = lookup_view except: pass if url is None: logger.error("Reverse for '%s' not found." % lookup_view) raise NoReverseMatch("Reverse for '%s' not found." % lookup_view) return url
def get_url(self, obj, view_name, request, format): """ Given an object, return the URL that hyperlinks to the object. May raise a `NoReverseMatch` if the `view_name` and `lookup_field` attributes are not configured to correctly match the URL conf. """ kwargs = {} for model_field, url_param in self.lookup_fields: attr = obj for field in model_field.split('.'): attr = getattr(attr, field) kwargs[url_param] = attr try: return reverse(view_name, kwargs=kwargs, request=request, format=format) except NoReverseMatch: pass raise NoReverseMatch()
def parse_url(lookup_view): if not lookup_view: raise ValueError("No lookup_view") url = None try: url = reverse_with_params( viewname=lookup_view["viewname"], args=lookup_view.get("args", []), query_string=lookup_view.get("query_string", None), ) except KeyError: # assume we've been passed a url try: resolve(lookup_view) url = lookup_view except Exception: pass if url is None: logger.error("Reverse for '%s' not found." % lookup_view) raise NoReverseMatch("Reverse for '%s' not found." % lookup_view) return url
def parse_url(lookup_view): url = None try: if "args" in lookup_view.keys(): url = reverse(viewname=lookup_view["viewname"], args=lookup_view["args"]) else: url = reverse(viewname=lookup_view["viewname"]) if "query_string" in lookup_view.keys(): url = url + "?" + lookup_view["query_string"] except KeyError: # assume we've been passed a url try: resolve(lookup_view) url = lookup_view except: pass if url is None: logger.error("Reverse for '%s' not found." % lookup_view) raise NoReverseMatch("Reverse for '%s' not found." % lookup_view) return url