Using {% url ??? %} in django templates

DjangoDjango TemplatesDjango Urls

Django Problem Overview


I have looked a lot on google for answers of how to use the 'url' tag in templates only to find many responses saying 'You just insert it into your template and point it at the view you want the url for'. Well no joy for me :( I have tried every permutation possible and have resorted to posting here as a last resort.

So here it is. My urls.py looks like this:

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}),
)

My 'views.py' in my 'login' directory looks like:

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))

and finally the main.html to which the login_view points looks like:

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

So why do I get 'NoReverseMatch' every time?

(on a slightly different note I had to use 'context_instance=RequestContext(request)' at the end of all my render-to-response's because otherwise it would not recognise {{ MEDIA_URL }} in my templates and I couldn't reference any css or js files. I'm not to sure why this is. Doesn't seem right to me)

Django Solutions


Solution 1 - Django

The selected answer is out of date and no others worked for me (Django 1.6 and [apparantly] no registered namespace.)

For Django 1.5 and later (from the docs)

> Warning > Don’t forget to put quotes around the function path or pattern name!

With a named URL you could do:

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

Just as easy if the view takes another parameter

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

Solution 2 - Django

Instead of importing the logout_view function, you should provide a string in your urls.py file:

So not (r'^login/', login_view),

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

That is the standard way of doing things. Then you can access the URL in your templates using:

{% url login.views.login_view %}

Solution 3 - Django

Make sure (django 1.5 and beyond) that you put the url name in quotes, and if your url takes parameters they should be outside of the quotes (I spent hours figuring out this mistake!).

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

Solution 4 - Django

The url template tag will pass the parameter as a string and not as a function reference to reverse(). The simplest way to get this working is adding a name to the view:

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

Solution 5 - Django

I run into same problem.

What I found from documentation, we should use namedspace.

in your case {% url login:login_view %}

Solution 6 - Django

Judging from your example, shouldn't it be {% url myproject.login.views.login_view %} and end of story? (replace myproject with your actual project name)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRobert JohnstoneView Question on Stackoverflow
Solution 1 - DjangoMike SView Answer on Stackoverflow
Solution 2 - DjangoMarcus WhybrowView Answer on Stackoverflow
Solution 3 - DjangoBogatyrView Answer on Stackoverflow
Solution 4 - DjangoBernhard VallantView Answer on Stackoverflow
Solution 5 - DjangoAlistView Answer on Stackoverflow
Solution 6 - DjangoYuji 'Tomita' TomitaView Answer on Stackoverflow