【问题标题】:Using {% url ??? %} in django templates使用 {% 网址 ??? %} 在 Django 模板中
【发布时间】:2011-06-03 17:17:45
【问题描述】:

我在 google 上查看了很多关于如何在模板中使用“url”标签的答案,结果却发现许多回复说“您只需将其插入模板并将其指向您想要 url 的视图”。好吧,我不高兴:(我已经尝试了所有可能的排列方式,并作为最后的手段才在这里发帖。

原来如此。我的 urls.py 看起来像这样:

from django.conf.urls.defaults import *
from login.views import *
from mainapp.views import *
import settings

# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
    # Example:
    # (r'^weclaim/', include('weclaim.foo.urls')),
    (r'^login/', login_view),
    (r'^logout/', logout_view),
    ('^$', main_view),

    # Uncomment the admin/doc line below and add 'django.contrib.admindocs' 
    # to INSTALLED_APPS to enable admin documentation:
    # (r'^admin/doc/', include('django.contrib.admindocs.urls')),

    # Uncomment the next line to enable the admin:
    (r'^admin/', include(admin.site.urls)),
    #(r'^static/(?P<path>.*)$', 'django.views.static.serve',{'document_root': '/home/arthur/Software/django/weclaim/templates/static'}),
    (r'^static/(?P<path>.*)$', 'django.views.static.serve',{'document_root': settings.MEDIA_ROOT}),
)

我的“登录”目录中的“views.py”如下所示:

from django.shortcuts import render_to_response, redirect
from django.template import RequestContext
from django.contrib import auth

def login_view(request):
    if request.method == 'POST':
        uname = request.POST.get('username', '')
        psword = request.POST.get('password', '')
        user = auth.authenticate(username=uname, password=psword)
        # if the user logs in and is active
        if user is not None and user.is_active:
            auth.login(request, user)
            return render_to_response('main/main.html', {}, context_instance=RequestContext(request))
            #return redirect(main_view)
        else:
            return render_to_response('loginpage.html', {'box_width': '402', 'login_failed': '1',}, context_instance=RequestContext(request))
    else:
        return render_to_response('loginpage.html', {'box_width': '400',}, context_instance=RequestContext(request))

def logout_view(request):
    auth.logout(request)
    return render_to_response('loginpage.html', {'box_width': '402', 'logged_out': '1',}, context_instance=RequestContext(request))

最后是 login_view 指向的 main.html:

<html>
<body>
test! <a href="{% url logout_view %}">logout</a>
</body>
</html>

那么为什么我每次都会得到“NoReverseMatch”?

*(在一个稍微不同的注释上,我必须在所有渲染到响应的末尾使用 'context_instance=RequestContext(request)' 因为否则它不会在我的模板中识别 {{ MEDIA_URL }} 并且我不能'不引用任何 css 或 js 文件。我不确定这是为什么。我觉得不对)*

【问题讨论】:

  • 您所说的context_instance=RequestContext(request) 是正确的,这是允许模板访问提供给所有模板的上下文变量所必需的。默认情况下,所有通用视图都会这样做,但您需要在自定义视图中自己完成。
  • 对我来说似乎有点奇怪,因为您将一直从模板访问您的 css 和 js 文件,以保持整个站点的一致性。因此,您不应该默认访问 {{ MEDIA_URL }} 吗?
  • 此处接受的答案不再有效
  • 添加一个新答案,然后我会接受

标签: django django-templates django-urls


【解决方案1】:

您应该在urls.py 文件中提供一个字符串,而不是导入logout_view 函数:

所以不是(r'^login/', login_view),

但是(r'^login/', 'login.views.login_view'),

这是做事的标准方式。然后您可以使用以下方法访问模板中的 URL:

{% url login.views.login_view %}

【讨论】:

  • 是的,绝对使用字符串。这样,您也可以使用前缀,而不必将所有视图函数都导入到 URLConf 中。
  • 我也试过这个,并且在渲染时得到了“Caught NoReverseMatch: Reverse for 'login.views.login_views' with arguments '()' and keyword arguments '{}' not found.'再次:(
  • 等等...从头开始!我等了 15 分钟,又试了一次,它奏效了(yippeeee !!!)。很好 1. 下一个问题。如果我在管理页面中只添加了一个站点,如何将其添加到 {% url ??? %}
  • 是的,这是一个 necro,但 URL 标签在 2015 年仍然困扰着我。如果他们不不断改变语法会有所帮助:
  • 因为我是从 google 来到这里的,我应该说对于 django 1.8+,将字符串作为视图参数传递已被弃用,并且很快将被删除。您实际上应该像在这篇文章中那样传递可调用对象。
【解决方案2】:

url 模板标签会将参数作为字符串传递,而不是作为对reverse() 的函数引用。最简单的方法是在视图中添加name

url(r'^/logout/' , logout_view, name='logout_view')

【讨论】:

  • 我试过了,但我得到'无效的语法(urls.py,第 14 行)':(
  • 真正奇怪的是它(PyCharm - 不错的应用程序)不会让我使用 >name='logout_view'
  • 函数reverse()在哪里定义的?
  • 在您的模板中使用 {% url 'logout_view' %} django.readthedocs.org/en/latest/intro/tutorial03.html
【解决方案3】:

从你的例子来看,不应该是{% url myproject.login.views.login_view %} 和故事的结尾吗? (将myproject替换为您的实际项目名称)

【讨论】:

  • 与上面的“Caught NoReverseMatch while rendering: Reverse for 'weclaim.login.views.login_views' with arguments '()' and keyword arguments '{}' not found.' (我假设我的项目名称与存储我所有代码的根目录同名)
【解决方案4】:

我遇到了同样的问题。

我从文档中发现,我们应该使用命名空间。

在你的情况下{% url login:login_view %}

【讨论】:

  • 现在更多地使用命名空间。使 URL 更具可读性,它们实际上对您有意义
  • 能否附上文档链接?
【解决方案5】:

所选答案已过时,没有其他人为我工作(Django 1.6 和 [显然] 没有注册的命名空间。)

对于 Django 1.5 及更高版本(来自the docs

警告 不要忘记在函数路径或模式名称周围加上引号!

使用命名 URL,您可以这样做:

(r'^login/', login_view, name='login'),
...
<a href="{% url 'login' %}">logout</a>

如果视图采用另一个参数,同样简单

def login(request, extra_param):
...
<a href="{% url 'login' 'some_string_containing_relevant_data' %}">login</a>

【讨论】:

  • 是的,我知道。我目前在 1.4 中使用{% load url from future %}。好地方
  • 应该选择这个作为答案。在较新的 django 版本中不推荐使用字符串进行反向匹配 url。
【解决方案6】:

确保(django 1.5 及更高版本)您将 url 名称放在引号中,如果您的 url 带有参数,它们应该在引号之外 (我花了几个小时来找出这个错误!) .

{% url 'namespace:view_name' arg1=value1 arg2=value2 as the_url %}
<a href="{{ the_url }}"> link_name </a>

【讨论】:

  • 我知道这是一个旧答案,但这确实帮助了我。我正在使用 django-norel,它是 Django 1.6 的一个分支,它也必须遇到这个问题,因为将 url 名称封装在引号中修复了我得到的 TypeError。
  • 使用正确的文档也有帮助,因为它们不断更改语法:1.4 中的{% url app_views.client client.id %}(无引号)、1.5 -1.7 中的{% url 'app_views.client' client.id %}(带引号)和{% url 'app-views-client' client.id %}(无下划线或点,只是破折号)在 1.8 中。
  • 天哪,我正计划尽快升级到 1.8。
猜你喜欢
  • 2020-01-09
  • 2021-08-07
  • 2017-03-05
  • 1970-01-01
  • 2012-08-23
  • 2012-07-03
  • 1970-01-01
  • 1970-01-01
  • 2012-08-18
相关资源
最近更新 更多