需要反转Django参数的名称

2024-03-02 21:26:03 发布

您现在位置:Python中文网/ 问答频道 /正文

背景

假设我有一个url模式,其中包含将我链接到django中的视图的参数:

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

假设我有一个thing和一个feature

^{pr2}$

现在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,如何获得反转该url所需的kwarg参数名列表?

我在找函数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现在是我需要提供给Django的reverse函数的每个关键字的列表,以便反转名为"thing_feature"的url。在

感谢任何帮助!在

解决方案

根据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]

Tags: thedjangonameurlforgetnamesfeature
2条回答

我首先要警告一下:使用公共API是不可能的。除此之外,我正在积极地为1.10重写URL分派器,因此这个方法很可能会在那个时候中断。在

首先,您需要获得正确的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

由于一个视图名称可以有多个具有不同kwarg的模式(尽管为了您自己的理智起见,您可能希望避免这种情况),所以这将返回每个可能的kwarg集的列表。通常,不同的设置是一侧的所需功率,另一侧的要求+可选功率。在

我还没有测试过这个,但是如果它不起作用,您可以在resolver.reverse_dict中查找一点来找出确切的细节。它的设计并没有考虑到可用性。在

您应该能够使用^{}来完成此操作

从文件中:

A ResolverMatch object can then be interrogated to provide information about the URL pattern that matches a URL:

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

特定于示例代码:

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

相关问题 更多 >