【问题标题】:How to get the current url name using Django?如何使用 Django 获取当前的 url 名称?
【发布时间】:2011-01-30 07:13:13
【问题描述】:

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

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

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

学生知道如何使用{% url %}。当他们必须根据当前的 URL 生成更完整的 URL 时,他们知道面临问题。最简单的方法是再次使用{% url %},但有一些变化。由于我们已经命名了 url,我们需要知道如何获取调用当前视图的 url 的名称。

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

【问题讨论】:

  • 我在寻找通过模板标签输出当前绝对网址的方法时不断发现这个问题...如果您也在寻找它,那就是:{{ request.get_full_path }}

标签: django django-urls urlconf


【解决方案1】:

我不知道这个功能在 Django 中存在多久了,但正如following article 所示,它可以在视图中实现如下:

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

如果您在每个模板中都需要它,那么编写模板请求可能是合适的。

编辑:应用新的 DJANGO 更新

跟随当前的 Django 更新:

Django 1.10 (link)

django.core.urlresolvers 模块导入在 喜欢它的新位置,django.urls

Django 2.0 (link)

django.core.urlresolvers 模块被移除,取而代之的是它的新模块 位置,django.urls

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

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

【讨论】:

  • 为什么?据我了解您的问题,其中一个重要部分是如何实现“既然我们已经命名了 url,我们需要知道如何获取调用当前视图的 url 的名称。”...跨度>
  • 其实卢卡斯那天我脾气暴躁,完全武断地放弃了你的答案。我很抱歉,因为这实际上是正确的答案。我将对其进行编辑以使其更加清晰。
  • resolve() 无法解析,如果您将查询字符串传递给它并简单地引发 404。get_full_path() 返回路径和查询字符串。您需要使用resolve(request.path_info)
  • 如果需要解析的不是current url,而是用户要重定向到的那个呢?什么是更通用的方法来实现这一点?康利欧文斯的回答有一个线索,但如果说轮子已经存在于引擎盖下的 Django 中,我宁愿不重新发明轮子。
  • 这似乎不适用于带有 i18n_patterns 的可翻译网址
【解决方案2】:

从 Django 1.5 开始,可以从请求对象中访问它

current_url = request.resolver_match.url_name

如果您想要 url 名称和命名空间

current_url = request.resolver_match.view_name

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

【讨论】:

  • 当我把它放在上下文处理器中时它工作了,但是控制台中显示了这个奇怪的错误:AttributeError: 'WSGIRequest' object has no attribute 'resolver_match'
  • 只有在调用所有请求中间件后才会将“resolver_match”添加到请求对象中。那是url被解析的时候。因此,您只能从视图中间件开始访问。 (中间件的 process_view 函数)。它在请求中间件功能中不可用。 (中间件的process_request函数)。
  • .view_name 如果你需要命名空间
  • 确实i18n_patterns一起工作(从Django 3.2开始);即:{% language language.code %}<a href="{% url request.resolver_match.view_name %}"....
【解决方案3】:

对于那些为其 url 模式命名的人,您可能会对请求的命名空间 url 名称感兴趣。在这种情况下,Django 将其命名为 view_name

request.resolver_match.view_name

# return: <namespace>:<url name>

【讨论】:

  • 谢谢,但这几乎是 @dariusz-niespodziany 早期答案的欺骗,不是吗? stackoverflow.com/a/31931833/1450294
  • 如果你没有命名你的urls.py,那么@dariusz-niespodziany 立即是reverse-able。但是如果你使用命名空间,那么resolver_match.url_name 不是直接的reverse-able。因此,您必须自己附加名称空间。因此,Django 没有自己做,而是在初始化时设置了.view_name
【解决方案4】:

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

    request.resolver_match.url_name

Django >1.8

【讨论】:

    【解决方案5】:

    澄清问题:“在一个视图中,假设恰好有一个这样的 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 的名称。

    【讨论】:

      【解决方案6】:

      试试request.path。这将获得当前请求的路径。

      【讨论】:

        【解决方案7】:

        【讨论】:

        • +1 这并不能解决问题,但确实解决了其中提出的一个问题。
        【解决方案8】:

        您的问题有点不清楚,但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 模块,并希望能帮助您指明正确的方向。

        【讨论】:

        • 谢谢,但我知道 :-) 我添加了一些解释以避免误解。
        猜你喜欢
        • 2019-02-28
        • 2023-03-24
        • 2013-12-06
        • 2016-11-02
        • 2016-12-02
        • 2018-04-20
        • 2021-08-24
        • 2020-04-02
        • 2017-09-09
        相关资源
        最近更新 更多