如何使用Django获取当前网址名称?


90

我必须根据当前URL动态构建一个URL。使用{% url %}标记是最简单的方法,但是我需要当前的URL名称才能动态生成新的URL。

如何获取附加到指向当前视图的urlconf的url名称?

编辑:我知道我可以使用手工手工制作url,get_absolute_url但是我宁愿避免使用它,因为它是讲座的一部分,我只想演示一种构建url的方法。

学生知道如何使用{% url %}。他们知道当他们必须根据当前URL生成更完整的URL时遇到问题。最简单的方法是{% url %}再次使用,但要有所不同。由于已命名为url,因此我们需要知道如何获取调用当前视图的url的名称。

编辑2:另一个用例是根据基础模板不同地显示基础模板的各个部分。还有其他方法(使用CSS和{%block%},但有时如果视图名称与链接匹配,能够删除base.html菜单项的标签就很好了。


6
在寻找通过模板标签输出当前绝对URL的方法时,我一直在寻找这个问题……如果您也正在寻找它,那就是:{{ request.get_full_path }}
Dolph

Answers:


134

我不知道此功能已经成为Django的一部分了,但是正如以下文章所示,可以在视图中通过以下方式实现:

   from django.core.urlresolvers import resolve
   current_url = resolve(request.path_info).url_name

如果在每个模板中都需要,则编写模板请求可能是适当的。

编辑:应用新的DJANGO更新

在当前的Django更新之后:

Django 1.10链接

django.core.urlresolvers模块导入不建议使用,而应使用其新位置,django.urls

Django 2.0链接

django.core.urlresolvers模块已被删除,以保留其新位置django.urls

因此,正确的做法是这样的:

from django.urls import resolve
current_url = resolve(request.path_info).url_name

为什么?据我了解您的问题,其中至关重要的部分是如何实现“自从我们为url命名以来,我们需要知道如何获取调用当前视图的url名称。” ...
Lukas Bünger2012年

1
其实卢卡斯那天我很脾气,完全任意地放弃了你的答案。我很抱歉,因为这实际上是正确的答案。我将对其进行编辑以使其更加明显。
e-satis 2012年

8
resolve()无法解析是否将查询字符串传递给它,而仅引发404。get_full_path()返回路径和查询字符串。您将需要使用resolve(request.path_info)
Can BurakÇilingir'2

如果不是current必须解析的URL,而是用户要重定向到的URL,该怎么办?有什么更通用的方法可以做到这一点?康利·欧文斯(Conley Owens)的答案很有道理,但是如果所说的轮子已经存在于Django的幕后,我宁愿不重新发明轮子。
哈桑·拜格

这似乎不适用于带有i18n_patterns的可翻译网址
guival,

109

从Django 1.5开始,可以从请求对象进行访问

    current_url = request.resolver_match.url_name

https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.resolver_match


当我将其放在上下文处理器中时,它可以工作,但是在控制台中显示了这个奇怪的错误:AttributeError: 'WSGIRequest' object has no attribute 'resolver_match'
fjsj 2013年

2
仅在调用所有请求中间件之后,“ resolver_match”才添加到请求对象。就是在URL解析的时候。因此,您只能从View中间件开始访问。(中间件的process_view函数)。它不会在请求中间件功能中提供。(中间件的process_request函数)。
Bharathwaaj

.view_name如果需要名称空间

27

对于那些为其URL模式添加命名空间的人,您可能会对请求的命名空间URL名称感兴趣。在这种情况下,Djangoview_name改为调用它。

request.resolver_match.view_name

# return: <namespace>:<url name>

谢谢,但这几乎是@ dariusz-niespodziany的早期回答的虚伪,不是吗?stackoverflow.com/a/31931833/1450294
Michael Scheper

5
如果没有命名空间,urls.py则@ dariusz-niespodziany可以立即reverse启用。但是,如果您使用的是名称空间,则resolver_match.url_name不能直接reverse使用。因此,您必须自己添加名称空间。因此,Django不用自己做,而是已经.view_name在初始化时设置了。
Yeo

15

这可以通过以下方式实现:

    request.resolver_match.url_name

Django> 1.8


4

问题的澄清:“在视图中,假设有一个这样的urlpattern,您如何获得指向它的urlpattern的名称。”

出于某些原因,这可能是合乎需要的:从视图内部,我们希望通过DRY方法将URL获取到同一视图(我们不想知道自己的urlpattern名称)。

简短的回答:教课不是很简单,但是在一两个小时内完成并放在GitHub上对您来说可能是一件有趣的事情。

如果确实要执行此操作,则必须继承RegexURLResolver的子类,并修改resolve方法以返回匹配的模式(从中可以获取模式名称),而不是视图和关键字/值对。 http://code.djangoproject.com/browser/django/trunk/django/core/urlresolvers.py#L142

然后,您可以创建使用此子类的装饰器或更合适的中间件,以获取模式名称并将该值存储在请求中的某个位置,以便视图可以使用它。

如果您确实想这样做,并且遇到了一些麻烦,请告诉我,我可能会帮助您。

对于您的班级,我只是让他们在视图或模板中对模式名称进行硬编码。我相信这是可以接受的方式。

更新: 我越想这件事,越不希望在视图中获取urlpattern名称。urlpattern参数与它们所指向的视图的参数完全无关。如果要指向某个URL,则需要了解urlpattern的工作原理,而不仅仅是视图的工作原理。如果您需要了解urlpattern的工作方式,则可能还需要了解urlpattern的名称。




1

您的问题尚不清楚,但是http://docs.djangoproject.com/en/dev/topics/http/urls/可能会为您提供帮助。

注意到Django如何处理请求特别有用:

当用户从您的Django支持的网站请求页面时,系统将使用以下算法来确定要执行的Python代码:

  1. Django确定要使用的根URLconf模块。通常,这是ROOT_URLCONF设置的值,但是如果传入的HttpRequest对象具有称为urlconf的属性(由中间件请求处理设置),则将使用其值代替ROOT_URLCONF设置。
  2. Django加载该Python模块并查找变量urlpatterns。这应该是Python列表,格式为django.conf.urls.defaults.patterns()返回的格式。
  3. Django按顺序运行每个URL模式,并在与请求的URL匹配的第一个停止。
  4. 一旦其中一个正则表达式匹配,Django就会导入并调用给定的视图,这是一个简单的Python函数。该视图通过HttpRequest作为其第一个参数,而在正则表达式中捕获的所有值作为其余参数传递。

如果您只想走完整路径,可以尝试:

http://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.get_full_path

希望对您有所帮助-它指示如何使用URLconf模块,并希望能为您指明正确的方向。


谢谢,但我知道:-)我添加了一些解释,以避免造成误解。
e-satis
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.