在Django模板中使用{% url ??? %}

103 投票
7 回答
237717 浏览
提问于 2025-04-16 09:25

我在谷歌上找了很多关于如何在模板中使用'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'文件在'login'目录下,内容是:

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'的错误呢?

(另外,我发现我在所有的render-to-response的末尾都必须使用'context_instance=RequestContext(request)',否则我的模板里就无法识别{{ MEDIA_URL }},我也无法引用任何css或js文件。我不太明白为什么会这样,这让我觉得不太对劲)

7 个回答

51

确保在使用 Django 1.5 及以后的版本时,把网址名称放在引号里。如果你的网址需要参数,这些参数应该放在引号 外面(我花了好几个小时才搞明白这个错误!)。

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

这个选中的答案已经过时了,其他的也没能帮到我(我用的是Django 1.6,而且似乎没有注册的命名空间)。

对于Django 1.5及以后的版本(可以参考官方文档

注意 别忘了在函数路径或模式名称周围加上引号!

使用命名的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>
64

与其在你的 urls.py 文件中直接导入 logout_view 函数,不如提供一个字符串。

所以,不要写成 (r'^login/', login_view),

而是应该写成 (r'^login/', 'login.views.login_view'),

这才是标准的做法。然后你可以在你的模板中通过以下方式访问这个网址:

{% url login.views.login_view %}

撰写回答