Apparently in the current trunk reversed urllookup is kind of(!!)
working.

After toying with it a little bit I found one issue:
The main method, reverse, only returns the resulting matched url. Not
the rule (the regex and extra arguments) it matched. There is no
reliable way of knowing which kwargs got matched and which ones have
been ignored. I needed to know to pass the unmatched arguments as
querystring. Moreover it would be nice to know what arguments have been
passed to the rule. For example adding the parameter https:True would
then allow me to build the urls as https.


But never mind, it already s quite usefull as it is. I made a template
helper tag, to use it in your templates.

"""
reversed urllookup tag

Usage:
---
{% load urlhelpers %}
{% url_for 'main.views.index' "request.method" request.path foo ok=
"bar" method=request.method sub=9 %}
---
The first parameter is the view the url will point to.
For the second and following parameters you can use named parameters
like foo=bar.
Parameters and named parameters will be evaluated. If it doesn't
evaluate then the string is used.
In the above example this means, assuming you use requestContext as
your context, that
"request.method" => request.method
foo => foo
"bar" => bar
request.method => GET

I'd be nice to have a middleware that prepopulated the named paramaters
if they have already been given for a certain view

If you copy/paste this code, be sure to remove references to logging,
rclogging (request cycly logging if you wondered) is my homebrewn
interface to python logging.
"""

from django.template import Library, Node, resolve_variable,
TemplateSyntaxError
from django.core.urlresolvers import reverse
from django.db.models import get_model
from lib.rclogging import logger
import re

register = Library()


def find_url_for_view(view , *args , **kwargs):
     # url = reverse(view, *args , **kwargs )
     # logger.debug(args)
     # logger.debug(kwargs)

     from django.conf import settings
     urlconf = settings.ROOT_URLCONF
     url = reverse(view,  args = args ,  kwargs = kwargs)

     # logger.debug(re.split(r"[/.]" , url))

     # now i want to append a query string
     # i want to use the unmatched kwargs for this
     # ideally reverse would also return the matched regexp, sadly it
doesn't
     # i'll naively see what values have been matched
     query_string = "&".join(["=".join([k, str(v)]) for k , v in
kwargs.items() if not str(v) in re.split(r"[/.]" , url)])
     logger.debug(query_string)
     if len(query_string) > 0:
         query_string = "?" + query_string

     return url + query_string

class ReversedUrlNode(Node):
    def __init__(self , view , *args , **kwargs):
        self.args = args
        self.kwargs = kwargs
        self.view = view

    def safe_resolve(self , var , context):
        try:
            outvar = resolve_variable(var , context)
        except:
            outvar = var
        logger.debug("%s = %s" % (var ,outvar) )
        return outvar

    def render(self , context):
        args = [self.safe_resolve(v , context) for v in self.args]
        kwargs = dict([(k, self.safe_resolve(v , context)) for k , v in
self.kwargs.items()])
        view = self.safe_resolve(self.view , context)
        try:
            url = find_url_for_view(view , *args , **kwargs)
        except:
            logger.warn("reversed lookup did a booboo")
            url = "n/a"
        # url = find_url_for_view(self.view , *args , **kwargs)
        return url

@register.tag()
def url_for(parser , token):
    raw = re.sub(r'\s*=\s*' , "=" , token.contents)
    # logger.debug(raw)
    bits=raw.split()
    if len(bits) < 2:
        raise TemplateSyntaxError, "url_for need atleast one argument:
url_for my.view"
    args = []
    kwargs = {}
    view = bits[1]
    for bit in bits[2:]:
        pos_is = bit.find("=")
        if pos_is == -1:
            args.append(bit)
        else:
            kwargs[bit[:pos_is]] = bit[1+pos_is:]
            # logger.debug("kwargs[%s] = %s" % (bit[:pos_is] ,
bit[1+pos_is:]))

    return ReversedUrlNode(view , *args , **kwargs)



A few gotcha's: As I didn't feel like rewriting the lookup
procedure (I guess it is still alpha at best anyways) I use an
extremely naïve way of determining whether an keyword argument
matched. I then build a querystring with the remaining armuments.
Needless to say, this might slipup..
The second: if the view you want to create the url for a view that does
does not already exists reversed urllookup will not work. (wile
unreversed throws a cuyu error page)
The third: I didn't want to throw errors, so if reverse lookup goes
wrong, "n/a" will be the url. I guess you'll want to change that
behaviour.


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-users
-~----------~----~----~----~------~----~------~--~---

Reply via email to