﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
2615	[patch] Make reversed url-resolving aware of matched kwargs and extra options	norjee@…	nobody	"The current reversed url-resolving only returned a matching url. This is fine for simple issues, but often more info is needed.

For example: 
- It is usefull to know which of the supplied kwargs have been matched, so one could, for example, supply the other ones in the query string.
- An url pattern can have default-arguments. These could be used to create a middleware that redirects to https if, for example, the default argument https:True has been supplied. It would be usefull to build a secure url with reversed url-resolving, but for that, the default arguments need to be known.

This patch introduced a new method, reverse_match (the old reverse method still returns the url, but uses reverse_match to find it), which returns a match-object:
{{{
class ReversedMatch:
    """"""
    url is te resulting url
    matched_args is a list with matched named args
    default_args a hash, with the associated default args
    """"""
    def __init__(self, url , matched_kwargs , default_args):
        self.url = url
        self.matched_kwargs = matched_kwargs
        self.default_args = default_args
            
    def __add__(self , other):
        new_default_args = self.default_args.copy() 
        new_default_args.update(other.default_args)
        return ReversedMatch(self.url + other.url , self.matched_kwargs + other.matched_kwargs , new_default_args)
    
    def get_unmatched_kwargs(self, kwargs):
        return dict([(k, v) for k , v in kwargs.items() if not k in self.matched_kwargs])
    
    def get_default_args(self):
        return self.default_args
    
    def get_url(self):
        return '/' + self.url
}}}

As an example, the follwing method appends builds an url through this new reversed url-lookup, and then appends the unmatched kwargs:
{{{
def find_url_for_view(view , *args , **kwargs):
     # url = reverse(view, *args , **kwargs )
     # logger.debug(args)
     # logger.debug(kwargs)
     
     match = reverse_match(view,  args = args ,  kwargs = kwargs)
     url = match.get_url()
     logger.debug(match.get_unmatched_kwargs(kwargs))
     logger.debug(match.get_default_args())
     # logger.debug(re.split(r""[/.]"" , url))
     
     # now i want to append a query string
     # i want to use the unmatched kwargs for this
     query_string = ""&amp;"".join([""="".join([k, str(v)]) for k , v in match.get_unmatched_kwargs(kwargs).items()])
     logger.debug(query_string)
     if len(query_string) > 0:
         query_string = ""?"" + query_string
         
     return url + query_string
}}}"	New feature	closed	Core (Other)		Normal	duplicate			Someday/Maybe	1	0	0	0	0	0
