Пример #1
0
def prepare_url_list(resolver, namespace_path='', namespace=''):
    for url_name in resolver.reverse_dict.keys():
        if not isinstance(url_name, str):
            continue
        url_name = force_str(url_name)
        formated_patterns = []
        for url_pattern in resolver.reverse_dict.getlist(url_name):
            for url_format, url_params in url_pattern[0]:
                formated_patterns.append({
                    'pattern': namespace_path + url_format,
                    'params': url_params
                })
        yield {'name': namespace + url_name, 'patterns': formated_patterns}

    for inner_ns, (inner_ns_path,
                   inner_resolver) in resolver.namespace_dict.items():
        inner_ns_path = namespace_path + inner_ns_path
        inner_ns = namespace + inner_ns + ':'

        if inner_ns_path:
            inner_resolver = urls.get_ns_resolver(inner_ns_path,
                                                  inner_resolver, ())
            inner_ns_path = ''

        for url_pattern in prepare_url_list(inner_resolver, inner_ns_path,
                                            inner_ns):
            yield url_pattern
Пример #2
0
def get_namespace_path_resolver(urlresolver, ns_path):
    for inner_ns, (inner_ns_path, inner_urlresolver) in \
            urlresolver.namespace_dict.items():
        if inner_ns == ns_path[0]:
            if hasattr(urlresolver, 'pattern'):
                inner_urlresolver = get_ns_resolver(
                    inner_ns_path, inner_urlresolver,
                    tuple(urlresolver.pattern.converters.items()))
            else:
                # Django 1.11.
                inner_urlresolver = get_ns_resolver(inner_ns_path,
                                                    inner_urlresolver)
            if len(ns_path) == 1:
                return inner_urlresolver
            else:
                return get_namespace_path_resolver(inner_urlresolver,
                                                   ns_path[1:])
    raise NoReverseMatch('Cannot find namespace %s' ':'.join(ns_path))
Пример #3
0
def urltemplate_namespaces(viewname, current_app=None, *args, **kwargs):
    urlconf = urls.get_urlconf()
    resolver = urls.get_resolver(urlconf)
    prefix = urls.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 urls.NoReverseMatch(
                    "%s is not a registered namespace inside '%s'" %
                    (key, ':'.join(resolved_path)))
            else:
                raise urls.NoReverseMatch("%s is not a registered namespace" %
                                          key)
    if ns_pattern:
        resolver = urls.get_ns_resolver(ns_pattern, resolver)

    return urltemplate_with_prefix(resolver, view, prefix, *args, **kwargs)
Пример #4
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 = get_resolver(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 = ''
    ns_converters = {}

    # if it's a local url permission already given, so we just return true
    if named_url.startswith('#'):

        class LocalUrlDummyView:
            @staticmethod
            def has_permission(user):
                return True

        return LocalUrlDummyView

    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
            try:
                ns_converters.update(resolver.pattern.converters)
            except Exception:
                pass
        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:
        try:
            resolver = get_ns_resolver(ns_pattern, resolver,
                                       tuple(ns_converters.items()))
        except Exception:
            resolver = 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__)
Пример #5
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 variable

    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:
            args = [inner_ns_path, inner_urlresolver]

            # https://github.com/ierror/django-js-reverse/issues/65
            if LooseVersion(django.get_version()) >= LooseVersion("2.0.6"):
                args.append(tuple(urlresolver.pattern.converters.items()))

            inner_urlresolver = urlresolvers.get_ns_resolver(*args)
            inner_ns_path = ''

        for x in prepare_url_list(inner_urlresolver, inner_ns_path, inner_ns):
            yield x
Пример #6
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:
            args = [inner_ns_path, inner_urlresolver]

            # https://github.com/ierror/django-js-reverse/issues/65
            if LooseVersion(django.get_version()) >= LooseVersion("2.0.6"):
                args.append(tuple(urlresolver.pattern.converters.items()))

            inner_urlresolver = urlresolvers.get_ns_resolver(*args)
            inner_ns_path = ''

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