Django - get parameter names needed for return url

Background

Say I have a url template with parameters that will link me to a view in django:

url( r'^things/(?P<thing_name>\w+)/features/(?P<feature_name>\w+)$', views.thingFeature, name='thing_feature' ), 

And let's say I have thing and feature :

 thing = Thing.objects.get(.....) feature = thing.feature_set.first() t_name = thing.name f_name = feature.name 

Now Django gives me a terrific opportunity to get a URL that leads me to a page dedicated to a specific function of a certain thing. I can do it like this:

 from django.core.urlresolvers import reverse url = reverse('thing_feature', thing_name=t_name, feature_name=f_name) # url == '/things/thing2/features/left-arm' 

Question

Now I came across a situation in which I need to specifically address. I am not looking for a workaround - I am looking for a solution to the following problem:

Given the URL name , how do I get a list of kwarg argument names needed to change this URL?

I am looking for the get_kwarg_names_for_url function. It behaves like this:

 url_kwarg_names = get_kwarg_names_for_url('thing_feature') # url_kwarg_names == ['thing_name', 'feature_name'] 

url_kwarg_names now a list of every keyword that I need to provide Django reverse functions to cancel the URL with the name "thing_feature" .

Any help is appreciated!

Decision

Based on the knbk answer, I was able to find the following solution:

 def get_kwarg_names_for_url(url_name): resolver = get_resolver(get_urlconf()) reverse_data = resolver.reverse_dict[url_name] pattern_list = reverse_data[0] ''' Need to specify the 1st pattern because url regexes can potentially have multiple kwarg arrangments - this function does not take this possibility into account. ''' first_pattern = pattern_list[0] ''' `first_pattern` is now of the form `(url_string, kwarg_list)` - all we are interested in is the 2nd value. ''' return first_pattern[1] 
+8
python django django-urls
source share
2 answers

I'll start with a fair warning: this is not possible using the public API. In addition, I am actively working on rewriting the URL manager for 1.10, so this method is likely to break by then.

First, you need to get the correct RegexURLResolver . If the view is not in the namespace, you can use reverse_dict to get a list of features and extract kwargs:

 def get_kwargs(view_name): resolver = urlresolvers.get_resolver() patterns = resolver.reverse_dict.getlist(view_name) kwargs = [] for possibility, pattern, defaults in patterns: for result, params in possibility: kwargs.append(params) return kwargs 

Since the view name can have several templates with different kwargs (although you would like to avoid this, for your own sanity), this will return a list of each set of possible kwargs. Typically, the different sets were the required kwargs on the one hand and required + additional kwargs on the other.

I have not tested this, but if it does not work, you can delve into resolver.reverse_dict to find out the exact specification. It has not been precisely designed for ease of use.

+2
source share

You must do this with resolve()

From Documents:

You can then query the ResolverMatch object to provide information about the URL pattern that matches the URL:

func, args, kwargs = resolve('/some/path/')

The specific code for your example:

 url = reverse('thing_feature') func, args, kwargs = resolve(url) # args == ['thing_name', 'feature_name'] 
0
source share

All Articles