2015-10-07 3 views
8

фон

Скажем, у меня есть шаблон URL-адрес с параметрами, которые связывают меня с видом на Джанго:Джанго - получить имена параметров, необходимых для обратного URL-адрес

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

и позволяет сказать, у меня есть thing и feature:

thing = Thing.objects.get(.....) 
feature = thing.feature_set.first() 

t_name = thing.name 
f_name = feature.name 

Теперь Django дает мне удивительную возможность получить URL, который приносит мне к странице, посвященной конкретной функции конкретного т Хин. Я могу сделать это так:

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

Вопрос

Теперь я наткнулся на ситуацию, мне нужно конкретно рассмотреть. Я не ищу обходные пути - Я ищу, чтобы решить следующую задачу:

Учитывая URL, name, как я могу получить список kwarg имен аргументов, необходимых для обратного, что URL?

Я ищу функцию get_kwarg_names_for_url. Он ведет себя так, как:

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

url_kwarg_names теперь список каждого ключевого слова мне нужно поставить в reverse функции Джанго для того, чтобы полностью изменить URL с именем "thing_feature".

Любая помощь приветствуется!

Решение

На основании ответа knbk, я был в состоянии придумать следующее решение:

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] 
+0

Я только что спустил кроличью нору: изменил URL-адрес, сопоставил URL-адрес с URL-адресом, скомпилировал регулярное выражение urlpattern и проверил «групповое выражение» регулярного выражения ... Мне здесь что-то не хватает. – Monkpit

+1

Проблема в том, что вы не можете отменить URL-адрес, прежде чем вы уже знаете требуемые имена параметров url. Django поднимет ошибку для 'reverse ('thing_feature')', потому что у нее отсутствуют необходимые kwargs! –

+0

Вы можете попробовать это http://stackoverflow.com/a/1275601 Я попробовал себя здесь и вместо этого использовал '.items()', он возвращает хороший список кортежей, в котором есть kwargs. Вы должны пойти глубже , похоже, хорошее начало, к сожалению, я иду домой сейчас и не может идти глубже. – Tiago

ответ

2

Начну с изрядным предупреждением: это не представляется возможным с помощью открытого API. Кроме того, я активно работаю над переписыванием диспетчера URL-адресов для 1.10, поэтому этот метод, скорее всего, сломается к тому времени.

Во-первых, вам нужно спрятать RegexURLResolver.Если представление не в пространстве имен, вы можете использовать reverse_dict, чтобы получить список возможностей, и извлечь 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 

Поскольку имя представления может иметь несколько моделей с разным kwargs (хотя вы хотите чтобы избежать этого для вашего собственного здравомыслия), это вернет список каждого набора возможных кваргов. Обычно разные наборы представляли собой требуемые kwargs с одной стороны и требовали + дополнительные kwargs с другой стороны.

Я не тестировал это, но если это не сработает, вы можете найти нужный код в resolver.reverse_dict, чтобы узнать точную информацию. Это не было точно спроектировано с учетом удобства использования.

+0

Вы, сэр, дикие. Ваш код работает не совсем правильно, но он дал мне более чем достаточно информации, чтобы сделать его функциональным. Я также не беспокоюсь о регулярных выражениях URL-адресов, что приводит к множественным договоренностям с kwarg. Обновлен мой вопрос, чтобы отразить то, что работало в конце. –

+0

p.s. Похоже, ты один из авторов джанго? –

+0

@GershomMaes Я являюсь автором, но не частью основной команды, хотя;) – knbk

0

Вы должны быть в состоянии сделать это с resolve()

Из документов:

Затем объект ResolverMatch можно опросить, чтобы предоставить информацию об URL-адресе p attern, который соответствует URL:

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

Конкретного вашему пример код:

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

Вы не можете передать имя URL-адреса 'resolve'. – ozgur

+0

@ozgur обновлен на основе вашего комментария. –

Смежные вопросы