[Fixed]-Receiving a NoReverseMatch error while trying to add the username to the url after login

1👍

Step 1. Move your index url to the last, and give it a pattern to accept username only. Moving index url to the last is important, or it will override all the others url in the same urls file, e.g., login, logout.

app_name = 'accounts'

urlpatterns = patterns(
    '',
    url(r'^login/', login_view, name='login'),
    url(r'^logout/', logout_view, name='logout'),
    url(r'^register/', register_view, name='register'),
    #
    # +------------ this url should come at last !!!!
    # |
    # v
    url(r'^(?P<username>[0-9a-zA-Z._]+)/$', login_required(views.IndexView.as_view()), name = 'index'), name = 'index'),
)

Step 2. redirect to your index url with the logined user name.

return redirect(reverse('accounts:index', args=(username, )))

EDIT 2 Fixing template error

According to your stack trace, the error occurred in your template, and django can’t reverse a url for index. After checking your code in your template, I found that, you have called a url function with accounts:index as parameter, but without specifying the username kwarg in your method call.

So you can fix the error with the code below:

{% if user %}
<li><a href="{% url 'accounts:index' user.username %}"><span class="glyphicon glyphicon-user"></span> {{ user.username }}</a></li>
{% endif %}
👤Enix

0👍

Django’s url accept pattern, that means, you can setup a url for home page like:

url(r'^(?P<username>[a-zA-Z]*)$', views.userhome, name = 'index'),

In your user’s index view, you will get a variable from url, so the function(same for Class-based-view) will like:

def userhome(request, username):

To use this url, you can use reverse function:

#after login...
return redirect(revers('index', args=[username]))

And here are some useful tips for you:

  1. Better write your decorator in your views.py, since writing in your urls.py will make it too messy.
  2. Try to user reverse function to get a url instead of writing in your code directly

For further information about reverse and url config, you may refer to Django’s doc.

0👍

Another way is to add the username in as a querystring in your redirect function. This way you don’t have to change your urls:

return redirect("/accounts/?username=%s" % user.username)

Additionally, you can get the user from request.user in the view (without having to add it to the url), which is what I’d recommend — other than if for aesthetic purposes you want it in the url.

Here’s another login function for reference that fixes some of the issues discussed in the comments of your question:

def login(request):

    username = request.POST.get('username')
    password = request.POST.get('password')
    if username and password:

        # Make sure its an active user, or else return an error message.
        user = authenticate(username=username, password=password)
        if user is not None and user.is_active:
            auth_login(request, user)
            next = request.session.get('next', 'root')
            return redirect(next)
        else:
            messages.warning(request, "Invalid username / password.")

    return render(request, 'login.html')

Leave a comment