def reverse(request, prefix, app_name, view_name, kwargs={}):
    _namespace = resolve(request.path).namespace
    if prefix is not None and app_name is not None:
        _namespace = prefix + '-' + app_name
    if _namespace:
        return _reverse(u':'.join([_namespace, view_name]), kwargs=kwargs)
    return _reverse(u':'.join([_namespace, view_name]), kwargs=kwargs)
Exemple #2
0
def edit(request,kind,object_id):
    """
    Edit model
    """

    (model,model_form) = _getModelInfo(kind)

    message = ""

    id = None
    key_name = None
    try:
        id = int(object_id)
    except ValueError:
        key_name = object_id

    object = get_object_or_404(model,key_name = key_name , id=id)

    if request.method == 'POST':
        form = model_form(request.POST,instance=object)
        if form.is_valid():
            
            #Old object was changed by the from, so it need to get a new copy
            object = get_object_or_404(model,key_name = key_name , id=id)
            new_object = form.save(commit = False)
            
            changelog = createChangelog(object,new_object,form.cleaned_data['log_message'])
            if changelog:                
            
                db.put([new_object,changelog])
                updateCachedObject(new_object)
                #TODO - Update loader cache
                
                return HttpResponseRedirect(new_object.get_absolute_url())
            else:
                message = _("Nothing changed. The form will not be saved")

    else:
        form = model_form(instance=object)

    view_object_link = None
    if object : 
        view_object_link = object.get_absolute_url()
        
    return render_to_response( 
        request,
        'gogogo/db/edit.html'
        ,{ "form" : form , 
           "object" : object,
           "kind" : kind,
           "message" : message,
           "history_link" : _reverse('gogogo.views.db.changelog.list') + "?kind=%s" % kind,
           "view_object_link" : view_object_link,
           "action" : _reverse('gogogo.views.db.edit',args=[kind,object_id]) ,
           })		
Exemple #3
0
def reverse(viewname, urlconf=None, args=None, kwargs=None, prefix=None, *vargs, **vkwargs):
    ct = currentThread()
    if ct in _urlconfs:
        # Special handling inside ApplicationContent.render; override urlconf
        # and prefix variables so that reverse works as expected.
        urlconf1, prefix1 = _urlconfs[ct]
        try:
            return _reverse(viewname, urlconf1, args, kwargs, prefix1, *vargs, **vkwargs)
        except NoReverseMatch:
            # fall through to calling reverse with default arguments
            pass

    return _reverse(viewname, urlconf, args, kwargs, prefix, *vargs, **vkwargs)
def reverse(request, prefix, app_name, view_name, kwargs={}):
    _namespace = resolve(request.path).namespace
    if not prefix:
        prefix = settings.SITE_PREFIX
    if app_name is not None:
        _namespace = prefix + '-' + app_name
    return _reverse(u':'.join([_namespace, view_name]), kwargs=kwargs)
Exemple #5
0
def reverse(viewname, kwargs=None, request=None, format=None):
    """
    Like the regular 'reverse' function, but returns fully qualified urls,
    and takes an additional 'format' argument.
    """
    if format:
        kwargs['format'] = format
    url = _reverse(viewname, kwargs=kwargs)
    return request.build_absolute_uri(url)
Exemple #6
0
def reverse(viewname, kwargs=None, request=None, format=None):
    """
    Like the regular 'reverse' function, but returns fully qualified urls,
    and takes an additional 'format' argument.
    """
    if format:
        kwargs['format'] = format
    url = _reverse(viewname, kwargs=kwargs)
    return request.build_absolute_uri(url)
Exemple #7
0
def add(request,kind):
    """
    Add new entry to database
    """

    (model,model_form) = _getModelInfo(kind)

    if request.method == 'POST':
        form = model_form(request.POST)
        
        if form.is_valid():
            instance = _createModelByForm(model,form)
            form = model_form(request.POST,instance = instance)

            instance = form.save(commit=False)		
            
            instance.save()

            changelog = createChangelog(None,instance,form.cleaned_data['log_message'])

            changelog.save()
            
            return HttpResponseRedirect(instance.get_absolute_url())
    elif request.method == 'GET':
        parent = None
        if "parent" in request.GET:
            parent = request.GET['parent']
        instance = _createModel(kind,parent)
        form = model_form(instance=instance)
        
    else:
        form = model_form()
        
    message = ""

    return render_to_response( 
        request,
        'gogogo/db/edit.html'
        ,{ "form" : form , 
           "kind" : kind,
           "message" : message,
           "history_link" : _reverse('gogogo.views.db.changelog.list') + "?kind=%s" % kind,
           "action" : _reverse('gogogo.views.db.add',args=[kind]) ,
           })		
Exemple #8
0
def reverse(viewname, params=None, absolute=False, **kwargs):
    """
    >>> reverse('create_location', args=["test"], params={"selected": "foo"})
    '/a/test/settings/locations/new/?selected=foo'
    """
    url = _reverse(viewname, **kwargs)
    if absolute:
        url = "{}{}".format(get_url_base(), url)
    if params:
        url = "{}?{}".format(url, urlencode(params))
    return url
def reverse(viewname, params=None, absolute=False, **kwargs):
    """
    >>> reverse('create_location', args=["test"], params={"selected": "foo"})
    '/a/test/settings/locations/new/?selected=foo'
    """
    url = _reverse(viewname, **kwargs)
    if absolute:
        url = "{}{}".format(get_url_base(), url)
    if params:
        url = "{}?{}".format(url, urlencode(params))
    return url
Exemple #10
0
def reverse(viewname, args=(), kwargs=None):
    """
    Return the URL associated with a view and specified parameters.
    If the regular expression used specifies an optional slash at 
    the end of the URL, add the slash.
    """
    if not kwargs:
        kwargs = {}
    url = _reverse(viewname, None, args, kwargs)
    if url[-2:] == '/?':
        url = url[:-1]
    return url
Exemple #11
0
def reverse(*args, **kwargs):
    """
    Django-Sities version of reverse method that
    return full urls (with domain, protocol, etc...)
    """

    url = _reverse(*args, **kwargs)
    site = base.get_current()

    url_tmpl = "{scheme}//{domain}{url}"
    scheme = site.scheme and "{0}:".format(site.scheme) or ""
    return url_tmpl.format(scheme=scheme, domain=site.domain, url=url)
def reverse(viewname, args=(), kwargs=None):
    """
    Return the URL associated with a view and specified parameters.
    If the regular expression used specifies an optional slash at 
    the end of the URL, add the slash.
    """
    if not kwargs:
        kwargs = {}
    url = _reverse(viewname, None, args, kwargs)
    if url[-2:] == '/?':
        url = url[:-1]
    return url
Exemple #13
0
def reverse(viewname, urlconf=None, args=None, kwargs=None, prefix=None, *vargs, **vkwargs):
    """
    This reverse replacement adds two new capabilities to the Django reverse method:

    - If reverse is called from inside ``ApplicationContent.process``, it
      automatically prepends the URL of the page the ``ApplicationContent``
      is attached to, thereby allowing ``reverse`` and ``{% url %}`` to
      return correct URLs without hard-coding the application integration
      point into the templates or URLconf files.
    - If the viewname contains a slash, the part before the slash is
      interpreted as the path to an URLconf file. This allows the template
      author to resolve URLs only reachable via an ``ApplicationContent``,
      even inside another application contents' ``process`` method::

          {% url registration.urls/auth_logout %}
    """

    if isinstance(viewname, basestring) and APPLICATIONCONTENT_RE.match(viewname):
        # try to reverse an URL inside another applicationcontent
        other_urlconf, other_viewname = viewname.split("/")

        if hasattr(_local, "urlconf") and other_urlconf == _local.urlconf[0]:
            return app_reverse(
                other_viewname, other_urlconf, args=args, kwargs=kwargs, prefix=prefix, *vargs, **vkwargs
            )

        import warnings

        warnings.warn(
            "Reversing URLs through a patched 'django.core.urlresolvers.reverse'"
            " function or using the 'urlconf/view_name' notation has been deprecated and"
            " support for it will be removed in FeinCMS v1.7."
            " Use 'feincms.content.application.models.app_reverse' or the 'app_reverse'"
            " template tag from 'applicationcontent_tags' directly.",
            DeprecationWarning,
            stacklevel=2,
        )

        return app_reverse(other_viewname, other_urlconf, args=args, kwargs=kwargs, prefix=prefix, *vargs, **vkwargs)

    if hasattr(_local, "urlconf"):
        # Special handling inside ApplicationContent.render; override urlconf
        # and prefix variables so that reverse works as expected.
        urlconf1, prefix1 = _local.urlconf
        try:
            return app_reverse(viewname, urlconf1, args, kwargs, prefix1, *vargs, **vkwargs)
        except NoReverseMatch:
            # fall through to calling reverse with default arguments
            pass

    return _reverse(viewname, urlconf, args, kwargs, prefix, *vargs, **vkwargs)
Exemple #14
0
def reverse(viewname, args=None, kwargs=None, site_id=None):
    """
    Django-Sities version of reverse method that
    return full urls (with domain, protocol, etc...)
    """

    if site_id is None:
        site = base.get_current()
    else:
        site = base.get_by_id(site_id)

    url = _reverse(viewname, args=args, kwargs=kwargs)
    url_tmpl = "{scheme}//{domain}{url}"

    scheme = site.scheme and "{0}:".format(site.scheme) or ""
    return url_tmpl.format(scheme=scheme, domain=site.domain, url=url)
Exemple #15
0
def reverse(viewname,
            urlconf=None,
            args=None,
            kwargs=None,
            prefix=None,
            *vargs,
            **vkwargs):
    """
    This reverse replacement adds two new capabilities to the Django reverse method:

    - If reverse is called from inside ``ApplicationContent.process``, it
      automatically prepends the URL of the page the ``ApplicationContent``
      is attached to, thereby allowing ``reverse`` and ``{% url %}`` to
      return correct URLs without hard-coding the application integration
      point into the templates or URLconf files.
    - If the viewname contains a slash, the part before the slash is
      interpreted as the path to an URLconf file. This allows the template
      author to resolve URLs only reachable via an ``ApplicationContent``,
      even inside another application contents' ``process`` method::

          {% url registration.urls/auth_logout %}
    """

    if isinstance(viewname,
                  basestring) and APPLICATIONCONTENT_RE.match(viewname):
        # try to reverse an URL inside another applicationcontent
        other_urlconf, other_viewname = viewname.split('/')

        if hasattr(_local, 'urlconf') and other_urlconf == _local.urlconf[0]:
            # We are reversing an URL from our own ApplicationContent
            return _reverse(other_viewname, other_urlconf, args, kwargs,
                            _local.urlconf[1], *vargs, **vkwargs)

        if not hasattr(_local, 'reverse_cache'):
            _local.reverse_cache = {}

        # Update this when more items are used for the proximity analysis below
        proximity_info = getattr(_local, 'proximity_info', None)
        if proximity_info:
            urlconf_cache_key = '%s_%s' % (other_urlconf, proximity_info[0])
        else:
            urlconf_cache_key = '%s_noprox' % other_urlconf

        if urlconf_cache_key not in _local.reverse_cache:
            # TODO do not use internal feincms data structures as much
            model_class = ApplicationContent._feincms_content_models[0]
            contents = model_class.objects.filter(
                urlconf_path=other_urlconf).select_related('parent')

            if proximity_info:
                # Poor man's proximity analysis. Filter by tree_id :-)
                try:
                    content = contents.get(parent__tree_id=proximity_info[0])
                except (model_class.DoesNotExist,
                        model_class.MultipleObjectsReturned):
                    try:
                        content = contents[0]
                    except IndexError:
                        content = None
            else:
                try:
                    content = contents[0]
                except IndexError:
                    content = None
            _local.reverse_cache[urlconf_cache_key] = content
        else:
            content = _local.reverse_cache[urlconf_cache_key]

        if content:
            # Save information from _urlconfs in case we are inside another
            # application contents' ``process`` method currently
            saved_cfg = getattr(_local, 'urlconf', None)

            # Initialize application content reverse hackery for the other application
            _local.urlconf = (other_urlconf, content.parent.get_absolute_url())

            try:
                url = reverse(other_viewname, other_urlconf, args, kwargs,
                              prefix, *vargs, **vkwargs)
            except:
                # We really must not fail here. We absolutely need to remove/restore
                # the _urlconfs information
                url = None

            if saved_cfg:
                _local.urlconf = saved_cfg
            else:
                del _local.urlconf

            # We found an URL somewhere in here... return it. Otherwise, we continue
            # below
            if url:
                return url

    if hasattr(_local, 'urlconf'):
        # Special handling inside ApplicationContent.render; override urlconf
        # and prefix variables so that reverse works as expected.
        urlconf1, prefix1 = _local.urlconf
        try:
            return _reverse(viewname, urlconf1, args, kwargs, prefix1, *vargs,
                            **vkwargs)
        except NoReverseMatch:
            # fall through to calling reverse with default arguments
            pass

    return _reverse(viewname, urlconf, args, kwargs, prefix, *vargs, **vkwargs)
Exemple #16
0
def reverse(view_name, *args, **kwargs):
    return _reverse(view_name, args=args, kwargs=kwargs)
Exemple #17
0
def app_reverse(viewname,
                urlconf,
                args=None,
                kwargs=None,
                prefix=None,
                language=None,
                *vargs,
                **vkwargs):
    """
    Reverse URLs from application contents

    Works almost like Django's own reverse() method except that it resolves
    URLs from application contents. The second argument, ``urlconf``, has to
    correspond to the URLconf parameter passed in the ``APPLICATIONS`` list
    to ``Page.create_content_type``::

        app_reverse('mymodel-detail', 'myapp.urls', args=...)

        or

        app_reverse('mymodel-detail', 'myapp.urls', kwargs=...)

    The second argument may also be a request object if you want to reverse
    an URL belonging to the current application content.
    """

    # First parameter might be a request instead of an urlconf path, so
    # we'll try to be helpful and extract the current urlconf from it
    appconfig = getattr(urlconf, '_feincms_extra_context',
                        {}).get('app_config', {})
    urlconf = appconfig.get('urlconf_path', urlconf)

    # vargs and vkwargs are used to send through additional parameters which are
    # uninteresting to us (such as current_app)

    # get additional cache keys from the page if available
    # refs https://github.com/feincms/feincms/pull/277/
    fn = getattr(_local, 'page_cache_key_fn', lambda: language
                 if language else '')
    cache_key_prefix = fn()

    app_cache_keys = {
        'none': '%s:app_%s_none' % (cache_key_prefix, urlconf),
    }
    proximity_info = getattr(_local, 'proximity_info', None)
    url_prefix = None

    if proximity_info:
        app_cache_keys.update({
            'all':
            '%s:app_%s_%s_%s_%s_%s' % ((
                cache_key_prefix,
                urlconf,
            ) + proximity_info),
            'tree':
            '%s:app_%s_%s' % (cache_key_prefix, urlconf, proximity_info[0]),
        })

    for key in ('all', 'tree', 'none'):
        try:
            url_prefix = _local.reverse_cache[app_cache_keys[key]]
            break
        except (AttributeError, KeyError):
            pass
    else:
        try:
            # Take the ApplicationContent class used by the current request
            model_class = _local.page_class.content_type_for(
                ApplicationContent)
        except AttributeError:
            model_class = None

        if not model_class:
            # Take any
            model_class = ApplicationContent._feincms_content_models[0]

        # TODO: Only active pages? What about multisite support?

        contents = model_class.objects.filter(urlconf_path=urlconf)

        # Helps select ApplicationContent for required language
        if not language is None and 'translations' in Page._feincms_extensions:
            contents = contents.filter(parent__language=language)

        contents = contents.select_related('parent')

        if proximity_info:
            # find the closest match within the same subtree
            tree_contents = contents.filter(parent__tree_id=proximity_info[0])
            if not len(tree_contents):
                # no application contents within the same tree
                cache_key = 'tree'
                try:
                    content = contents[0]
                except IndexError:
                    content = None
            elif len(tree_contents) == 1:
                cache_key = 'tree'
                # just one match within the tree, use it
                content = tree_contents[0]
            else:  # len(tree_contents) > 1
                cache_key = 'all'
                try:
                    # select all ancestors and descendants and get the one with
                    # the smallest difference in levels
                    content = (tree_contents.filter(
                        parent__rght__gt=proximity_info[2],
                        parent__lft__lt=proximity_info[1])
                               | tree_contents.filter(
                                   parent__lft__lte=proximity_info[2],
                                   parent__lft__gte=proximity_info[1],
                               )).extra({
                                   'level_diff':
                                   "abs(level-%d)" % proximity_info[3]
                               }).order_by('level_diff')[0]
                except IndexError:
                    content = tree_contents[0]
        else:
            cache_key = 'none'
            try:
                content = contents[0]
            except IndexError:
                content = None

        if content:
            if urlconf in model_class.ALL_APPS_CONFIG:
                # We have an overridden URLconf
                urlconf = model_class.ALL_APPS_CONFIG[urlconf]['config'].get(
                    'urls', urlconf)

            if not hasattr(_local, 'reverse_cache'):
                _local.reverse_cache = {}

            # Reimplementation of Page.get_absolute_url because we are quite likely
            # to hit infinite recursion if we call models.permalink because of the
            # reverse monkey patch
            url = content.parent._cached_url[1:-1]
            if url:
                prefix = _reverse('feincms_handler', args=(url, ))
                # prefix must always ends with a slash
                prefix += '/' if prefix[-1] != '/' else ''

            else:
                prefix = _reverse('feincms_home')

            _local.reverse_cache[app_cache_keys[cache_key]] = url_prefix = (
                urlconf, prefix)

    if url_prefix:
        return _reverse(viewname,
                        url_prefix[0],
                        args=args,
                        kwargs=kwargs,
                        prefix=url_prefix[1],
                        *vargs,
                        **vkwargs)
    raise NoReverseMatch("Unable to find ApplicationContent for '%s'" %
                         urlconf)
Exemple #18
0
def reverse(viewname, urlconf=None, args=None, kwargs=None, prefix=None, *vargs, **vkwargs):
    """
    This reverse replacement adds two new capabilities to the Django reverse method:

    - If reverse is called from inside ``ApplicationContent.process``, it
      automatically prepends the URL of the page the ``ApplicationContent``
      is attached to, thereby allowing ``reverse`` and ``{% url %}`` to
      return correct URLs without hard-coding the application integration
      point into the templates or URLconf files.
    - If the viewname contains a slash, the part before the slash is
      interpreted as the path to an URLconf file. This allows the template
      author to resolve URLs only reachable via an ``ApplicationContent``,
      even inside another application contents' ``process`` method::

          {% url registration.urls/auth_logout %}
    """

    if isinstance(viewname, basestring) and APPLICATIONCONTENT_RE.match(viewname):
        # try to reverse an URL inside another applicationcontent
        other_urlconf, other_viewname = viewname.split('/')

        if hasattr(_local, 'urlconf') and other_urlconf == _local.urlconf[0]:
            # We are reversing an URL from our own ApplicationContent
            return _reverse(other_viewname, other_urlconf, args, kwargs, _local.urlconf[1], *vargs, **vkwargs)

        if not hasattr(_local, 'reverse_cache'):
            _local.reverse_cache = {}

        # Update this when more items are used for the proximity analysis below
        proximity_info = getattr(_local, 'proximity_info', None)
        if proximity_info:
            urlconf_cache_key = '%s_%s' % (other_urlconf, proximity_info[0])
        else:
            urlconf_cache_key = '%s_noprox' % other_urlconf

        if urlconf_cache_key not in _local.reverse_cache:
            # TODO do not use internal feincms data structures as much
            model_class = ApplicationContent._feincms_content_models[0]
            contents = model_class.objects.filter(
                urlconf_path=other_urlconf).select_related('parent')

            if proximity_info:
                # Poor man's proximity analysis. Filter by tree_id :-)
                try:
                    content = contents.get(parent__tree_id=proximity_info[0])
                except (model_class.DoesNotExist, model_class.MultipleObjectsReturned):
                    try:
                        content = contents[0]
                    except IndexError:
                        content = None
            else:
                try:
                    content = contents[0]
                except IndexError:
                    content = None
            _local.reverse_cache[urlconf_cache_key] = content
        else:
            content = _local.reverse_cache[urlconf_cache_key]

        if content:
            # Save information from _urlconfs in case we are inside another
            # application contents' ``process`` method currently
            saved_cfg = getattr(_local, 'urlconf', None)

            # Initialize application content reverse hackery for the other application
            _local.urlconf = (other_urlconf, content.parent.get_absolute_url())

            try:
                url = reverse(other_viewname, other_urlconf, args, kwargs, prefix, *vargs, **vkwargs)
            except:
                # We really must not fail here. We absolutely need to remove/restore
                # the _urlconfs information
                url = None

            if saved_cfg:
                _local.urlconf = saved_cfg
            else:
                del _local.urlconf

            # We found an URL somewhere in here... return it. Otherwise, we continue
            # below
            if url:
                return url

    if hasattr(_local, 'urlconf'):
        # Special handling inside ApplicationContent.render; override urlconf
        # and prefix variables so that reverse works as expected.
        urlconf1, prefix1 = _local.urlconf
        try:
            return _reverse(viewname, urlconf1, args, kwargs, prefix1, *vargs, **vkwargs)
        except NoReverseMatch:
            # fall through to calling reverse with default arguments
            pass

    return _reverse(viewname, urlconf, args, kwargs, prefix, *vargs, **vkwargs)
Exemple #19
0
def reverse(viewname, urlconf=None, args=None, kwargs=None, prefix=None, *vargs, **vkwargs):
    """
    This reverse replacement adds two new capabilities to the Django reverse method:

    - If reverse is called from inside ``ApplicationContent.process``, it
      automatically prepends the URL of the page the ``ApplicationContent``
      is attached to, thereby allowing ``reverse`` and ``{% url %}`` to
      return correct URLs without hard-coding the application integration
      point into the templates or URLconf files.
    - If the viewname contains a slash, the part before the slash is
      interpreted as the path to an URLconf file. This allows the template
      author to resolve URLs only reachable via an ``ApplicationContent``,
      even inside another application contents' ``process`` method::

          {% url registration.urls/auth_logout %}
    """

    if isinstance(viewname, basestring) and APPLICATIONCONTENT_RE.match(viewname):
        # try to reverse an URL inside another applicationcontent
        other_urlconf, other_viewname = viewname.split('/')

        if hasattr(_local, 'urlconf') and other_urlconf == _local.urlconf[0]:
            # We are reversing an URL from our own ApplicationContent
            return _reverse(other_viewname, other_urlconf, args, kwargs, _local.urlconf[1], *vargs, **vkwargs)

        if not hasattr(_local, 'reverse_cache'):
            _local.reverse_cache = {}


        # try different cache keys of descending specificity, this one always works
        urlconf_cache_keys = {
            'none': '%s_noprox' % other_urlconf,
        }

        # when we have more proximity info, we can use more specific cache keys
        proximity_info = getattr(_local, 'proximity_info', None)
        if proximity_info:
            urlconf_cache_keys.update({
                'all': '%s_%s_%s_%s_%s' % ((other_urlconf,) + proximity_info),
                'tree': '%s_%s' % (other_urlconf, proximity_info[0]),
            })

        for key in ('all', 'tree', 'none'):
            if key in urlconf_cache_keys and urlconf_cache_keys[key] in _local.reverse_cache:
                content = _local.reverse_cache[urlconf_cache_keys[key]]
                break
        else:
            # TODO do not use internal feincms data structures as much
            model_class = ApplicationContent._feincms_content_models[0]
            contents = model_class.objects.filter(
                urlconf_path=other_urlconf).select_related('parent')

            if proximity_info:
                # find the closest match within the same subtree
                tree_contents = contents.filter(parent__tree_id=proximity_info[0])
                if not len(tree_contents):
                    # no application contents within the same tree
                    cache_key = 'tree'
                    try:
                        content = contents[0]
                    except IndexError:
                        content = None
                elif len(tree_contents) == 1:
                    cache_key = 'tree'
                    # just one match within the tree, use it
                    content = tree_contents[0]
                else: # len(tree_contents) > 1
                    cache_key = 'all'
                    try:
                        # select all ancestors and descendants and get the one with
                        # the smallest difference in levels
                        content = (tree_contents.filter(
                            parent__rght__gt=proximity_info[2],
                            parent__lft__lt=proximity_info[1]
                        ) | tree_contents.filter(
                            parent__lft__lte=proximity_info[2],
                            parent__lft__gte=proximity_info[1],
                        )).extra({'level_diff':"abs(level-%d)" % proximity_info[3]}
                            ).order_by('level_diff')[0]
                    except IndexError:
                        content = tree_contents[0]
            else:
                cache_key = 'none'
                try:
                    content = contents[0]
                except IndexError:
                    content = None
            _local.reverse_cache[urlconf_cache_keys[cache_key]] = content

        if content:
            # Save information from _urlconfs in case we are inside another
            # application contents' ``process`` method currently
            saved_cfg = getattr(_local, 'urlconf', None)

            # Initialize application content reverse hackery for the other application
            _local.urlconf = (other_urlconf, content.parent.get_absolute_url())

            try:
                url = reverse(other_viewname, other_urlconf, args, kwargs, prefix, *vargs, **vkwargs)
            except:
                # We really must not fail here. We absolutely need to remove/restore
                # the _urlconfs information
                url = None

            if saved_cfg:
                _local.urlconf = saved_cfg
            else:
                del _local.urlconf

            # We found an URL somewhere in here... return it. Otherwise, we continue
            # below
            if url:
                return url

    if hasattr(_local, 'urlconf'):
        # Special handling inside ApplicationContent.render; override urlconf
        # and prefix variables so that reverse works as expected.
        urlconf1, prefix1 = _local.urlconf
        try:
            return _reverse(viewname, urlconf1, args, kwargs, prefix1, *vargs, **vkwargs)
        except NoReverseMatch:
            # fall through to calling reverse with default arguments
            pass

    return _reverse(viewname, urlconf, args, kwargs, prefix, *vargs, **vkwargs)
Exemple #20
0
def reverse(viewname, *args, **kwargs):
    return django_settings.APP_PREFIX + _reverse(viewname, *args, **kwargs)
Exemple #21
0
def reverse(viewname,
            urlconf=None,
            args=None,
            kwargs=None,
            prefix=None,
            *vargs,
            **vkwargs):
    """
    This reverse replacement adds two new capabilities to the Django reverse method:

    - If reverse is called from inside ``ApplicationContent.process``, it
      automatically prepends the URL of the page the ``ApplicationContent``
      is attached to, thereby allowing ``reverse`` and ``{% url %}`` to
      return correct URLs without hard-coding the application integration
      point into the templates or URLconf files.
    - If the viewname contains a slash, the part before the slash is
      interpreted as the path to an URLconf file. This allows the template
      author to resolve URLs only reachable via an ``ApplicationContent``,
      even inside another application contents' ``process`` method::

          {% url registration.urls/auth_logout %}
    """

    if isinstance(viewname,
                  basestring) and APPLICATIONCONTENT_RE.match(viewname):
        # try to reverse an URL inside another applicationcontent
        other_urlconf, other_viewname = viewname.split('/')

        if hasattr(_local, 'urlconf') and other_urlconf == _local.urlconf[0]:
            # We are reversing an URL from our own ApplicationContent
            return _reverse(other_viewname, other_urlconf, args, kwargs,
                            _local.urlconf[1], *vargs, **vkwargs)

        if not hasattr(_local, 'reverse_cache'):
            _local.reverse_cache = {}

        # try different cache keys of descending specificity, this one always works
        urlconf_cache_keys = {
            'none': '%s_noprox' % other_urlconf,
        }

        # when we have more proximity info, we can use more specific cache keys
        proximity_info = getattr(_local, 'proximity_info', None)
        if proximity_info:
            urlconf_cache_keys.update({
                'all':
                '%s_%s_%s_%s_%s' % ((other_urlconf, ) + proximity_info),
                'tree':
                '%s_%s' % (other_urlconf, proximity_info[0]),
            })

        for key in ('all', 'tree', 'none'):
            if key in urlconf_cache_keys and urlconf_cache_keys[
                    key] in _local.reverse_cache:
                content = _local.reverse_cache[urlconf_cache_keys[key]]
                break
        else:
            # TODO do not use internal feincms data structures as much
            model_class = ApplicationContent._feincms_content_models[0]
            contents = model_class.objects.filter(
                urlconf_path=other_urlconf).select_related('parent')

            if proximity_info:
                # find the closest match within the same subtree
                tree_contents = contents.filter(
                    parent__tree_id=proximity_info[0])
                if not len(tree_contents):
                    # no application contents within the same tree
                    cache_key = 'tree'
                    try:
                        content = contents[0]
                    except IndexError:
                        content = None
                elif len(tree_contents) == 1:
                    cache_key = 'tree'
                    # just one match within the tree, use it
                    content = tree_contents[0]
                else:  # len(tree_contents) > 1
                    cache_key = 'all'
                    try:
                        # select all ancestors and descendants and get the one with
                        # the smallest difference in levels
                        content = (tree_contents.filter(
                            parent__rght__gt=proximity_info[2],
                            parent__lft__lt=proximity_info[1])
                                   | tree_contents.filter(
                                       parent__lft__lte=proximity_info[2],
                                       parent__lft__gte=proximity_info[1],
                                   )).extra({
                                       'level_diff':
                                       "abs(level-%d)" % proximity_info[3]
                                   }).order_by('level_diff')[0]
                    except IndexError:
                        content = tree_contents[0]
            else:
                cache_key = 'none'
                try:
                    content = contents[0]
                except IndexError:
                    content = None
            _local.reverse_cache[urlconf_cache_keys[cache_key]] = content

        if content:
            # Save information from _urlconfs in case we are inside another
            # application contents' ``process`` method currently
            saved_cfg = getattr(_local, 'urlconf', None)

            # Initialize application content reverse hackery for the other application
            _local.urlconf = (other_urlconf, content.parent.get_absolute_url())

            try:
                url = reverse(other_viewname, other_urlconf, args, kwargs,
                              prefix, *vargs, **vkwargs)
            except:
                # We really must not fail here. We absolutely need to remove/restore
                # the _urlconfs information
                url = None

            if saved_cfg:
                _local.urlconf = saved_cfg
            else:
                del _local.urlconf

            # We found an URL somewhere in here... return it. Otherwise, we continue
            # below
            if url:
                return url

    if hasattr(_local, 'urlconf'):
        # Special handling inside ApplicationContent.render; override urlconf
        # and prefix variables so that reverse works as expected.
        urlconf1, prefix1 = _local.urlconf
        try:
            return _reverse(viewname, urlconf1, args, kwargs, prefix1, *vargs,
                            **vkwargs)
        except NoReverseMatch:
            # fall through to calling reverse with default arguments
            pass

    return _reverse(viewname, urlconf, args, kwargs, prefix, *vargs, **vkwargs)
Exemple #22
0
def app_reverse(viewname, urlconf, args=None, kwargs=None, prefix=None, *vargs, **vkwargs):
    """
    Reverse URLs from application contents

    Works almost like Django's own reverse() method except that it resolves
    URLs from application contents. The second argument, ``urlconf``, has to
    correspond to the URLconf parameter passed in the ``APPLICATIONS`` list
    to ``Page.create_content_type``::

        app_reverse('mymodel-detail', 'myapp.urls', args=...)

        or

        app_reverse('mymodel-detail', 'myapp.urls', kwargs=...)
    """

    # First parameter might be a request instead of an urlconf path, so
    # we'll try to be helpful and extract the current urlconf from it
    appconfig = getattr(urlconf, '_feincms_extra_context', {}).get('app_config', {})
    urlconf = appconfig.get('urlconf_path', urlconf)

    # vargs and vkwargs are used to send through additional parameters which are
    # uninteresting to us (such as current_app)

    app_cache_keys = {
        'none': 'app_%s_none' % urlconf,
        }
    proximity_info = getattr(_local, 'proximity_info', None)
    url_prefix = None

    if proximity_info:
        app_cache_keys.update({
            'all': 'app_%s_%s_%s_%s_%s' % ((urlconf,) + proximity_info),
            'tree': 'app_%s_%s' % (urlconf, proximity_info[0]),
            })

    for key in ('all', 'tree', 'none'):
        try:
            url_prefix = _local.reverse_cache[app_cache_keys[key]]
            break
        except (AttributeError, KeyError):
            pass
    else:
        try:
            # Take the ApplicationContent class used by the current request
            model_class = _local.page_class.content_type_for(ApplicationContent)
        except AttributeError:
            model_class = None

        if not model_class:
            # Take any
            model_class = ApplicationContent._feincms_content_models[0]

        # TODO: Only active pages? What about multisite support?
        contents = model_class.objects.filter(urlconf_path=urlconf).select_related('parent')

        if proximity_info:
            # find the closest match within the same subtree
            tree_contents = contents.filter(parent__tree_id=proximity_info[0])
            if not len(tree_contents):
                # no application contents within the same tree
                cache_key = 'tree'
                try:
                    content = contents[0]
                except IndexError:
                    content = None
            elif len(tree_contents) == 1:
                cache_key = 'tree'
                # just one match within the tree, use it
                content = tree_contents[0]
            else: # len(tree_contents) > 1
                cache_key = 'all'
                try:
                    # select all ancestors and descendants and get the one with
                    # the smallest difference in levels
                    content = (tree_contents.filter(
                        parent__rght__gt=proximity_info[2],
                        parent__lft__lt=proximity_info[1]
                    ) | tree_contents.filter(
                        parent__lft__lte=proximity_info[2],
                        parent__lft__gte=proximity_info[1],
                    )).extra({'level_diff':"abs(level-%d)" % proximity_info[3]}
                        ).order_by('level_diff')[0]
                except IndexError:
                    content = tree_contents[0]
        else:
            cache_key = 'none'
            try:
                content = contents[0]
            except IndexError:
                content = None

        if content:
            if urlconf in model_class.ALL_APPS_CONFIG:
                # We have an overridden URLconf
                urlconf = model_class.ALL_APPS_CONFIG[urlconf]['config'].get(
                    'urls', urlconf)

            if not hasattr(_local, 'reverse_cache'):
                _local.reverse_cache = {}

            # Reimplementation of Page.get_absolute_url because we are quite likely
            # to hit infinite recursion if we call models.permalink because of the
            # reverse monkey patch
            url = content.parent._cached_url[1:-1]
            if url:
                prefix = _reverse('feincms_handler', args=(url,))
            else:
                prefix = _reverse('feincms_home')

            _local.reverse_cache[app_cache_keys[cache_key]] = url_prefix = (
                urlconf, prefix)

    if url_prefix:
        return _reverse(viewname,
            url_prefix[0],
            args=args,
            kwargs=kwargs,
            prefix=url_prefix[1],
            *vargs, **vkwargs)
    raise NoReverseMatch("Unable to find ApplicationContent for '%s'" % urlconf)
Exemple #23
0
def reverse(view_name, *args, **kwargs):
    """More convient url reverse"""
    return _reverse(view_name, args=args, kwargs=kwargs)
Exemple #24
0
def reverse(to, *args, **kwargs):
    from django.core.urlresolvers import reverse as _reverse
    return _reverse(to, args=args, kwargs=kwargs)