使用{%url ??? django模板中的%}


83

我在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文件。我不确定为什么会这样。对我来说似乎不正确)*


1
您所说的context_instance=RequestContext(request)正确,这是允许模板访问提供给所有模板的上下文变量所必需的。默认情况下,这对于所有通用视图都是完成的,但是您需要在自定义视图中自己做。
Marcus Whybrow

我觉得有些奇怪,因为您将一直从模板访问css和js文件,以保持整个站点的一致性。因此,默认情况下您是否应该不能访问{{MEDIA_URL}}?
罗伯·约翰斯顿

1
此处接受的答案不再有效
Dan Gayle '18

添加一个新答案,然后我会接受
罗伯特·约翰斯顿

Answers:


54

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

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

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

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

{% url login.views.login_view %}

2
是的,绝对使用字符串。这样,您还可以使用前缀,而不必将所有视图函数导入URLConf。
Sri Raghavan

我也尝试过此操作,并得到了“渲染时捕获了NoReverseMatch:反向查找'login.views.login_views',未找到参数'()'和关键字参数'{}'。” 再次:(
罗伯·约翰斯顿

等等...抓痒!我等了15分钟,再试一次就成功了(yippeeee !!!)。不错1.下一个问题。如果只有一个网站已添加到管理页面中,我该如何在{%url?%}
罗伯·约翰斯通

是的,这是一个死灵,但URL标记在2015年仍然困扰着我。如果他们不不断更改语法,这将有所帮助:
Dave

6
仅仅因为我来自Google,我应该说,对于django 1.8+,不赞成将字符串作为view参数传递,并将很快将其删除。实际上,您应该像本文中那样传递callable。
user3599803

104

所选答案已经过时,没有其他人为我工作(Django 1.6,[似乎]没有注册的名称空间。)

对于Django 1.5及更高版本(来自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
是的,我知道。我{% load url from future %}目前在1.4中使用。好地方
Robert Johnstone 2014年

5
应该选择它作为答案。在较新的Django版本中,不建议将字符串用于反向匹配的url。
Sumudu

44

确保(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。
robobrobro

2
使用正确的文档也有帮助,因为它们会不断更改语法: {% url app_views.client client.id %}1.4中{% url 'app_views.client' client.id %}(不带引号),1.5 -1.7中(带引号)和{% url 'app-views-client' client.id %}1.8中(不带下划线或点,仅是短划线)。
戴夫

噢,上帝,我打算很快升级到1.8。
Bogatyr,2015年

17

url模板标签将通过参数作为一个字符串,而不是作为一个函数引用reverse()。使此工作最简单的方法是name在视图中添加一个:

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

我试过了,但是得到了'无效的语法(urls.py,第14行)':(
罗伯·约翰斯顿

真正奇怪的是,它(PyCharm-不错的应用程序)不允许我像上面那样使用> name ='logout_view'<,而无需推荐库导入(libxml2mod.name或unicodedata.name或twisted.trial.runner。名称)
罗伯特·约翰斯顿

函数reverse()定义在哪里?
CodyBugstein 2014年

在模板中使用{%url'logout_view'%} django.readthedocs.org/en/latest/intro/tutorial03.html
Juan Rojas

12

我遇到了同样的问题。

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

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


如今,使用名称空间的次数越来越多。使URL更具可读性,它们实际上对您来说意味着某些
Robert Johnstone

您可以包括文档链接吗?
geoidesic '18

1

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


与上面的“渲染时捕获NoReverseMatch”相同:反转“ weclaim.login.views.login_views”,未找到参数“()”和关键字参数“ {}”。(我假设我的项目名称与所有代码存储在其中的根目录相同)
Robert Johnstone
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.