Ejemplo n.º 1
0
def prepare_url_list(urlresolver, namespace_path="", namespace=""):
    """
    returns list of tuples [(<url_name>, <url_patern_tuple> ), ...]
    """
    exclude_ns = getattr(settings, "JS_REVERSE_EXCLUDE_NAMESPACES",
                         JS_EXCLUDE_NAMESPACES)

    if namespace[:-1] in exclude_ns:
        return

    for url_name in list(urlresolver.reverse_dict.keys()):
        if isinstance(url_name, (text_type, str)):
            url_patterns = []
            for url_pattern in urlresolver.reverse_dict.getlist(url_name):
                url_patterns += [[namespace_path + pat[0], pat[1]]
                                 for pat in url_pattern[0]]
            yield [namespace + url_name, url_patterns]

    for inner_ns, (inner_ns_path, inner_urlresolver) in list(
            urlresolver.namespace_dict.items()):
        inner_ns_path = namespace_path + inner_ns_path
        inner_ns = namespace + inner_ns + ":"

        # if we have inner_ns_path, reconstruct a new resolver so that we can
        # handle regex substitutions within the regex of a namespace.
        if inner_ns_path:
            inner_urlresolver = urlresolvers.get_ns_resolver(
                inner_ns_path, inner_urlresolver)
            inner_ns_path = ""

        for x in prepare_url_list(inner_urlresolver, inner_ns_path, inner_ns):
            yield x
def prepare_url_list(urlresolver, namespace_path='', namespace=''):
    """
    returns list of tuples [(<url_name>, <url_patern_tuple> ), ...]
    """
    exclude_ns = getattr(settings, 'JS_REVERSE_EXCLUDE_NAMESPACES', JS_EXCLUDE_NAMESPACES)

    if namespace[:-1] in exclude_ns:
        return

    for url_name in urlresolver.reverse_dict.keys():
        if isinstance(url_name, (text_type, str)):
            url_patterns = []
            for url_pattern in urlresolver.reverse_dict.getlist(url_name):
                url_patterns += [
                    [namespace_path + pat[0], pat[1]] for pat in url_pattern[0]
                ]
            yield [namespace + url_name, url_patterns]

    for inner_ns, (inner_ns_path, inner_urlresolver) in \
            urlresolver.namespace_dict.items():
        inner_ns_path = namespace_path + inner_ns_path
        inner_ns = namespace + inner_ns + ':'

        # if we have inner_ns_path, reconstruct a new resolver so that we can
        # handle regex substitutions within the regex of a namespace.
        if inner_ns_path:
            inner_urlresolver = urlresolvers.get_ns_resolver(inner_ns_path,
                                                             inner_urlresolver)
            inner_ns_path = ''

        for x in prepare_url_list(inner_urlresolver, inner_ns_path, inner_ns):
            yield x
Ejemplo n.º 3
0
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.
    """
    warnings.warn("urls_by_namespace is deprecated. Please view django-angular documentation for new way to manage URLs",
                  DeprecationWarning)

    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, six.string_types):
        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 as 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)
    resolver = get_ns_resolver(ns_pattern, resolver)
    return dict((name, iri_to_uri(resolver._reverse_with_prefix(name, prefix, *args, **kwargs)))
                for name in resolver.reverse_dict.keys() if isinstance(name, six.string_types))
Ejemplo n.º 4
0
def urltemplate_namespaces(viewname, current_app=None, *args, **kwargs):
    urlconf = urlresolvers.get_urlconf()
    resolver = urlresolvers.get_resolver(urlconf)
    prefix = urlresolvers.get_script_prefix()

    parts = viewname.split(':')
    parts.reverse()
    view = parts[0]
    path = parts[1:]

    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 as key:
            if resolved_path:
                raise urlresolvers.NoReverseMatch("%s is not a registered namespace inside '%s'" % (key, ':'.join(resolved_path)))
            else:
                raise urlresolvers.NoReverseMatch("%s is not a registered namespace" % key)
    if ns_pattern:
        resolver = urlresolvers.get_ns_resolver(ns_pattern, resolver)

    return urltemplate_with_prefix(resolver, view, prefix, *args, **kwargs)
Ejemplo n.º 5
0
def build_url_template(viewname, kwargs=[], urlconf=None, prefix=None, current_app=None):
    resolver = get_resolver(urlconf)

    if prefix is None:
        prefix = get_script_prefix()

    kwargs = list(kwargs)

    parts = viewname.split(':')
    parts.reverse()
    view = parts[0]
    path = parts[1:]

    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 as 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)
    if ns_pattern:
        resolver = get_ns_resolver(ns_pattern, resolver)

    possibilities = resolver.reverse_dict.getlist(view)
    prefix_norm, prefix_args = normalize(prefix)[0]
    for entry in possibilities:
        if len(entry) == 3:
            possibility, pattern, defaults = entry
        else:
            possibility, pattern = entry
            defaults = {}

        for result, params in possibility:
            if set(kwargs + list(defaults)) != set(params + list(defaults) + prefix_args):
                continue

            unicode_kwargs = dict([(k, '%(' + force_text(k) + ')s') for k in kwargs])
            unicode_kwargs.update(defaults)
            return (prefix_norm + result) % unicode_kwargs

    raise NoReverseMatch("Reverse for '%s' with keyword arguments '%s' not "
            "found." % (viewname, kwargs))
Ejemplo n.º 6
0
def build_url_template(viewname,
                       kwargs=[],
                       urlconf=None,
                       prefix=None,
                       current_app=None):
    resolver = get_resolver(urlconf)

    if prefix is None:
        prefix = get_script_prefix()

    kwargs = list(kwargs)

    parts = viewname.split(':')
    parts.reverse()
    view = parts[0]
    path = parts[1:]

    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 as 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)
    if ns_pattern:
        resolver = get_ns_resolver(ns_pattern, resolver)

    possibilities = resolver.reverse_dict.getlist(view)
    prefix_norm, prefix_args = normalize(prefix)[0]
    for entry in possibilities:
        if len(entry) == 3:
            possibility, pattern, defaults = entry
        else:
            possibility, pattern = entry
            defaults = {}

        for result, params in possibility:
            if set(kwargs + list(defaults)) != set(params + list(defaults) +
                                                   prefix_args):
                continue

            unicode_kwargs = dict([(k, '%(' + force_text(k) + ')s')
                                   for k in kwargs])
            unicode_kwargs.update(defaults)
            return (prefix_norm + result) % unicode_kwargs

    raise NoReverseMatch(
        "Reverse for '%s' with keyword arguments '%s' not found." %
        (viewname, kwargs))
Ejemplo n.º 7
0
            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)
    if ns_pattern:
        resolver = get_ns_resolver(ns_pattern, resolver)

    possibilities = resolver.reverse_dict.getlist(view)
    prefix_norm, prefix_args = normalize(prefix)[0]
    for entry in possibilities:
        if len(entry) == 3:
            possibility, pattern, defaults = entry
        else:
            possibility, pattern = entry
            defaults = {}

        for result, params in possibility:
            if set(kwargs + defaults.keys()) != set(params + defaults.keys() + prefix_args):
                continue

            unicode_kwargs = dict([(k, u'#{' + force_unicode(k) + u'}') for k in kwargs])
Ejemplo n.º 8
0
def prepare_url_list(urlresolver, namespace_path='', namespace=''):
    """
    returns list of tuples [(<url_name>, <url_patern_tuple> ), ...]
    """
    exclude_ns = getattr(settings, 'JS_REVERSE_EXCLUDE_NAMESPACES', JS_EXCLUDE_NAMESPACES)
    include_only_ns = getattr(settings, 'JS_REVERSE_INCLUDE_ONLY_NAMESPACES', JS_INCLUDE_ONLY_NAMESPACES)

    if exclude_ns and include_only_ns:
        raise ImproperlyConfigured(
            'Neither use JS_REVERSE_EXCLUDE_NAMESPACES nor JS_REVERSE_INCLUDE_ONLY_NAMESPACES setting')

    if namespace[:-1] in exclude_ns:
        return

    include_only_allow = True  # include_only state varible

    if include_only_ns != []:
        # True mean that ns passed the test
        in_on_empty_ns = False
        in_on_is_in_list = False
        in_on_null = False

        # Test urls without ns
        if namespace == '' and '' in include_only_ns:
            in_on_empty_ns = True

        # check if nestead ns isn't subns of include_only ns
        # e.g. ns = "foo:bar" include_only = ["foo"] -> this ns will be used
        # works for ns = "lorem:ipsum:dolor" include_only = ["lorem:ipsum"]
        # ns "lorem" will be ignored but "lorem:ipsum" & "lorem:ipsum:.." won't
        for ns in include_only_ns:
            if ns != "" and namespace[:-1].startswith(ns):
                in_on_is_in_list = True
                break

        # Test if isn't used "\0" flag
        # use "foo\0" to add urls just from "foo" not from subns "foo:bar"
        if namespace[:-1] + '\0' in include_only_ns:
            in_on_null = True

        include_only_allow = in_on_empty_ns or in_on_is_in_list or in_on_null

    if include_only_allow:
        for url_name in urlresolver.reverse_dict.keys():
            if isinstance(url_name, (text_type, str)):
                url_patterns = []
                for url_pattern in urlresolver.reverse_dict.getlist(url_name):
                    url_patterns += [
                        [namespace_path + pat[0], pat[1]] for pat in url_pattern[0]]
                yield [namespace + url_name, url_patterns]

    for inner_ns, (inner_ns_path, inner_urlresolver) in \
            urlresolver.namespace_dict.items():
        inner_ns_path = namespace_path + inner_ns_path
        inner_ns = namespace + inner_ns + ':'

        # if we have inner_ns_path, reconstruct a new resolver so that we can
        # handle regex substitutions within the regex of a namespace.
        if inner_ns_path:
            inner_urlresolver = urlresolvers.get_ns_resolver(inner_ns_path,
                                                             inner_urlresolver)
            inner_ns_path = ''

        for x in prepare_url_list(inner_urlresolver, inner_ns_path, inner_ns):
            yield x
Ejemplo n.º 9
0
def view_from_url(named_url):  # noqa
    """
    Finds and returns the view class from a named url
    """
    # code below is `stolen` from django's reverse method
    resolver = urlresolvers.get_resolver(urlresolvers.get_urlconf())

    if type(named_url) in (list, tuple):
        named_url = named_url[0]
    parts = named_url.split(':')
    parts.reverse()
    view = parts[0]
    path = parts[1:]
    current_path = None
    resolved_path = []
    ns_pattern = ''

    while path:
        ns = path.pop()
        current_ns = current_path.pop() if current_path else None

        # 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_ns and current_ns in app_list:
                # If we are reversing for a particular app,
                # use that namespace
                ns = current_ns
            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

        if ns != current_ns:
            current_path = None

        try:
            extra, resolver = resolver.namespace_dict[ns]
            resolved_path.append(ns)
            ns_pattern = ns_pattern + extra
        except KeyError as 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)
    if ns_pattern:
        resolver = urlresolvers.get_ns_resolver(ns_pattern, resolver)

    # custom code, get view from reverse_dict
    reverse_dict = resolver.reverse_dict.dict()
    for key, url_obj in reverse_dict.items():
        if url_obj == reverse_dict[view] \
                and key != view:
            module = importlib.import_module(key.__module__)
            return getattr(module, key.__name__)
Ejemplo n.º 10
0
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, six.string_types):
        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 as 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)
    resolver = get_ns_resolver(ns_pattern, resolver)
    return dict(
        (name,
         iri_to_uri(
             resolver._reverse_with_prefix(name, prefix, *args, **kwargs)))
        for name in resolver.reverse_dict.keys()
        if (isinstance(name, six.string_types)
            and 'datasets-detail' not in name and 'swagger' not in name
            and 'organizations-detail' not in name and 'simple_api_test' not in
            name and 'data_files-mapping-suggestions' not in name))
Ejemplo n.º 11
0
            pass

        try:
            extra, resolver = resolver.namespace_dict[ns]
            resolved_path.append(ns)
            ns_pattern = ns_pattern + extra
        except KeyError, key:
            if resolved_path:
                raise urlresolvers.NoReverseMatch(
                    "%s is not a registered namespace inside '%s'" %
                    (key, ':'.join(resolved_path)))
            else:
                raise urlresolvers.NoReverseMatch(
                    "%s is not a registered namespace" % key)
    if ns_pattern:
        resolver = urlresolvers.get_ns_resolver(ns_pattern, resolver)

    return urltemplate_with_prefix(resolver, view, prefix, *args, **kwargs)


@register.simple_tag(takes_context=True)
def urltemplate(context, viewname, *args, **kwargs):
    """
    Creates URI template in a similar way to how ``url`` tags work but leaving parts of
    a URI to be filled in by a client. See :rfc:`6570` for more information.

    Names of parts are taken from named groups in URL regex pattern used for the view,
    or as a part's sequence number (zero-based) for unnamed groups. You can pre-fill
    some parts by specifying them as additional arguments to the tag.

    .. warning:: Tag cannot check if pre-fill values specified will really match back
Ejemplo n.º 12
0
                # 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 urlresolvers.NoReverseMatch("%s is not a registered namespace inside '%s'" % (key, ':'.join(resolved_path)))
            else:
                raise urlresolvers.NoReverseMatch("%s is not a registered namespace" % key)
    if ns_pattern:
        resolver = urlresolvers.get_ns_resolver(ns_pattern, resolver)

    return urltemplate_with_prefix(resolver, view, prefix, *args, **kwargs)

@register.simple_tag(takes_context=True)
def urltemplate(context, viewname, *args, **kwargs):
    """
    Creates URI template in a similar way to how ``url`` tags work but leaving parts of
    a URI to be filled in by a client. See :rfc:`6570` for more information.

    Names of parts are taken from named groups in URL regex pattern used for the view,
    or as a part's sequence number (zero-based) for unnamed groups. You can pre-fill
    some parts by specifying them as additional arguments to the tag.

    .. warning:: Tag cannot check if pre-fill values specified will really match back
                 the URL regex pattern, so make sure yourself that they do.
Ejemplo n.º 13
0
            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)
    resolver = get_ns_resolver(ns_pattern, resolver)
    return dict(
        (name,
         iri_to_uri(
             resolver._reverse_with_prefix(name, prefix, *args, **kwargs)))
        for name in resolver.reverse_dict.keys()
        if isinstance(name, basestring))
Ejemplo n.º 14
0
def fuzzy_reverse(viewname, urlconf=None, args=None, kwargs=None, prefix=None, current_app=None):
    """
    from django/core/urlresolvers.py
    Unmodified reverse (just need to use our modified version of get_resolver)

    With the modified BRegexURLResolver retrieved through get_resolver this will
    not error when you pass in extra args (it assumes proper order and ignores
    trailing "extra" args) OR kwargs (it assumes you are passing at least the
    required keyworded arguments)

    It will still error if you pass both args AND kwargs at the same time.
    """
    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 isinstance(viewname, basestring):
        view = viewname
    else:
        parts = viewname.split(':')
        parts.reverse()
        view = parts[0]
        path = parts[1:]

        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, e:
                if resolved_path:
                    raise NoReverseMatch(
                        "%s is not a registered namespace inside '%s'" %
                        (e, ':'.join(resolved_path)))
                else:
                    raise NoReverseMatch("%s is not a registered namespace" %
                                         e)
        if ns_pattern:
            resolver = get_ns_resolver(ns_pattern, resolver)
Ejemplo n.º 15
0
def wild_reverse(viewname, kwargs, urlconf=None, current_app=None):
    """
    Returns the reverse url using as many of the given kwargs as possible.
    """

    # copy/paste from django.core.urlresolvers.reverse

    if urlconf is None:
        urlconf = get_urlconf()
    resolver = get_resolver(urlconf)

    prefix = get_script_prefix()

    if not isinstance(viewname, six.string_types):
        view = viewname
    else:
        parts = viewname.split(':')
        parts.reverse()
        view = parts[0]
        path = parts[1:]

        if current_app:
            current_path = current_app.split(':')
            current_path.reverse()
        else:
            current_path = None

        resolved_path = []
        ns_pattern = ''
        while path:
            ns = path.pop()
            current_ns = current_path.pop() if current_path else None

            # 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_ns and current_ns in app_list:
                    # If we are reversing for a particular app,
                    # use that namespace
                    ns = current_ns
                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

            if ns != current_ns:
                current_path = None

            try:
                extra, resolver = resolver.namespace_dict[ns]
                resolved_path.append(ns)
                ns_pattern = ns_pattern + extra
            except KeyError as 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)
        if ns_pattern:
            resolver = get_ns_resolver(ns_pattern, resolver)

    # /end copy/paste

    # this part adapted from
    # django.core.urlresolvers.RegexURLResolver._reverse_with_prefix

    text_kwargs = {k: force_text(v) for (k, v) in kwargs.items()}

    if not resolver._populated:
        resolver._populate()

    original_lookup = lookup_view = view
    try:
        if resolver._is_callback(lookup_view):
            lookup_view = get_callable(lookup_view, True)
    except (ImportError, AttributeError) as e:
        raise NoReverseMatch("Error importing '%s': %s." % (lookup_view, e))

    try:
        # note: this doesn't cover the possibility of multiple patterns returned
        params = resolver.reverse_dict[lookup_view][0][0][1]
        ok_kwargs = dict(((param, kwargs[param]) for param in params))
    except KeyError:
        # this covers both statements above
        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 wild keyword arguments "
                             "'%s' not found." % (lookup_view_s, kwargs))

    # /end adaptation

    return force_text(
        iri_to_uri(resolver._reverse_with_prefix(view, prefix, **ok_kwargs)))
Ejemplo n.º 16
0
def prepare_url_list(urlresolver, namespace_path='', namespace=''):
    """
    returns list of tuples [(<url_name>, <url_patern_tuple> ), ...]
    """
    exclude_ns = getattr(settings, 'JS_REVERSE_EXCLUDE_NAMESPACES', JS_EXCLUDE_NAMESPACES)
    include_only_ns = getattr(settings, 'JS_REVERSE_INCLUDE_ONLY_NAMESPACES', JS_INCLUDE_ONLY_NAMESPACES)

    if exclude_ns and include_only_ns:
        raise ImproperlyConfigured(
            'Neither use JS_REVERSE_EXCLUDE_NAMESPACES nor JS_REVERSE_INCLUDE_ONLY_NAMESPACES setting')

    if namespace[:-1] in exclude_ns:
        return

    include_only_allow = True  # include_only state varible

    if include_only_ns != []:
        # True mean that ns passed the test
        in_on_empty_ns = False
        in_on_is_in_list = False
        in_on_null = False

        # Test urls without ns
        if namespace == '' and '' in include_only_ns:
            in_on_empty_ns = True

        # check if nestead ns isn't subns of include_only ns
        # e.g. ns = "foo:bar" include_only = ["foo"] -> this ns will be used
        # works for ns = "lorem:ipsum:dolor" include_only = ["lorem:ipsum"]
        # ns "lorem" will be ignored but "lorem:ipsum" & "lorem:ipsum:.." won't
        for ns in include_only_ns:
            if ns != "" and namespace[:-1].startswith(ns):
                in_on_is_in_list = True
                break

        # Test if isn't used "\0" flag
        # use "foo\0" to add urls just from "foo" not from subns "foo:bar"
        if namespace[:-1] + '\0' in include_only_ns:
            in_on_null = True

        include_only_allow = in_on_empty_ns or in_on_is_in_list or in_on_null

    if include_only_allow:
        for url_name in urlresolver.reverse_dict.keys():
            if isinstance(url_name, (text_type, str)):
                url_patterns = []
                for url_pattern in urlresolver.reverse_dict.getlist(url_name):
                    url_patterns += [
                        [namespace_path + pat[0], pat[1]] for pat in url_pattern[0]]
                yield [namespace + url_name, url_patterns]

    for inner_ns, (inner_ns_path, inner_urlresolver) in \
            urlresolver.namespace_dict.items():
        inner_ns_path = namespace_path + inner_ns_path
        inner_ns = namespace + inner_ns + ':'

        # if we have inner_ns_path, reconstruct a new resolver so that we can
        # handle regex substitutions within the regex of a namespace.
        if inner_ns_path:
            inner_urlresolver = urlresolvers.get_ns_resolver(inner_ns_path,
                                                             inner_urlresolver)
            inner_ns_path = ''

        for x in prepare_url_list(inner_urlresolver, inner_ns_path, inner_ns):
            yield x