menu

Questions & Answers

Django: NoReverseMatch not a valid view function or pattern name

I have a django project with a structure like this:

my_project
|_ UserSignUp
  |_ urls.py
  |_ views.py
|_ Mainpage
  |_ urls.py
  |_ views.py
|_ my_project
  |_ urls.py
  |_ settings.py

My problem is as follows: I can access mysite.com/index and mysite.com/login just fine. But if I try to open mysite.com/signup I encounter a 500 Internal Server Error, more precisely an Error is thrown:

NoReverseMatch at /signup/
Reverse for 'login' not found. 'login' is not a valid view function or pattern name.

Of course I already googled the error but did not encounter anything particularly helpful. The descriptions I found explained errors, in which an url of an app had been tried to access, then failing because the namespace of the app was not provided in the url tag. In my case I am inside an app and want to access an url of the project root. As far as I know it should be automatically resolved and even if not, I don't know how to tell django to please look into the root urls. Is django not checking the root urls really cause of the problem or is there another thing I set up wrong? How can I fix this?

My root urls.py:

from django.contrib import admin
from django.urls import path
from django.conf.urls import include
from django.contrib.auth import views as auth_views

urlpatterns = [
    path('', include('Mainpage.urls')),
    path('index/', include('Mainpage.urls')),
    path('mainpage/', include('Mainpage.urls')),
    path('home/', include('Mainpage.urls')),
    path('login/', auth_views.LoginView.as_view(template_name='login/login.html', redirect_field_name='index')),
    path('signup/', include('UserSignUp.urls')),
    path('logout', auth_views.LogoutView.as_view(template_name='logout/logout.html', next_page='index')),
    path('admin/', admin.site.urls),
]

My UserSignUp urls.py:

from django.urls import path
from django.conf.urls import include
from UserSignUp import views

urlpatterns = [
    path(r'', views.signup, name='signup'),
    path(r'account_activation_sent/', views.account_activation_sent, name='account_activation_sent'),
    path(r'activate/', views.activate, name='activate')
]

My UserSignUp views.py:

from django.contrib.auth import login
from django.contrib.auth.models import User
from django.contrib.sites.shortcuts import get_current_site
from django.shortcuts import render, redirect
from django.utils.encoding import force_bytes, force_text
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
from django.template.loader import render_to_string
from UserSignUp.forms import SignUpForm
from UserSignUp.tokens import account_activation_token


def signup(request):
    if request.method == 'POST':
        form = SignUpForm(request.POST)
        if form.is_valid():
            user = form.save(commit=False)
            user.is_active = False
            user.save()
            current_site = get_current_site(request)
            subject = 'Activate Your MySite Account'
            message = render_to_string('account_activation_email.html', {
                'user': user,
                'domain': current_site.domain,
                'uid': urlsafe_base64_encode(force_bytes(user.pk)),
                'token': account_activation_token.make_token(user),
            })
            user.email_user(subject, message)
            return redirect('signup/account_activation_sent')
    else:
        form = SignUpForm()
    return render(request, 'UserSignUp/signup.html', {'form': form})


def account_activation_sent(request):
    return render(request, 'UserSignUp/account_activation_sent.html')


def activate(request, uidb64, token):
    try:
        uid = force_text(urlsafe_base64_decode(uidb64))
        user = User.objects.get(pk=uid)
    except (TypeError, ValueError, OverflowError, User.DoesNotExist):
        user = None

    if user is not None and account_activation_token.check_token(user, token):
        user.is_active = True
        user.profile.email_confirmed = True
        user.save()
        login(request, user)
        return redirect('index')
    else:
        return render(request, 'UserSignUp/account_activation_invalid.html')

The signup.html:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Signup</title>
  </head>
  <body>
    <header>
      <h1>My Site</h1>
      {% if user.is_authenticated %}
        <a href="{% url 'logout' %}">logout</a>
      {% else %}
        <a href="{% url 'login' %}">login</a> / <a href="{% url 'signup' %}">signup</a> #<----- here it encounters error
      {% endif %}
      <hr>
    </header>
    <main>
        <h2>Sign up</h2>
  <form method="post">
    {% csrf_token %}
    {% for field in form %}
      <p>
        {{ field.label_tag }}<br>
        {{ field }}
        {% if field.help_text %}
          <small style="color: grey">{{ field.help_text }}</small>
        {% endif %}
        {% for error in field.errors %}
          <p style="color: red">{{ error }}</p>
        {% endfor %}
      </p>
    {% endfor %}
    <button type="submit">Sign up</button>
  </form>
    </main>
  </body>
</html>
Comments:
2023-01-20 00:55:13
I have the same problem but mine is coming in when the account_ activation.html template is called. I get the error: italic_Error during template rendering In template ...\accounts\activation_request.html, error at line 6 Reverse for 'activate' not found. 'activate' is not a valid view function or pattern name._italic
2023-01-20 00:55:13
activation_request.html {% autoescape off %} Hi {{ user.first_name}}, Please click the following link to confirm your account http://{{ domain }}{% url 'activate' uiddb64=uid token=token %} % endautoescape %}
2023-01-20 00:55:13
urlpatterns = [ path('register/', register_account, name='register'), path('login/', login_request, name='login'), path("logout/", LogoutView.as_view(), name="logout"), path('sent/', activation_sent_view, name='activation_sent'), path('activate/<slug:uiddb64>/<slug:token>', activate, name='activate'), path('index', index_view, name='index'), ]
2023-01-20 00:55:13
Here is my Traceback dpaste.com/FYV7NMAST
2023-01-20 00:55:13
Figured out what my problem was. I had included a namespace in my app urls. Everything is working after removing it
Answers(1) :

You need to specify the name of login and logout views in urls.py

urlpatterns = [
    # rest of your URL configs
    path('login/', auth_views.LoginView.as_view(template_name='login/login.html', redirect_field_name='index'),
         name='login'),
    path('logout', auth_views.LogoutView.as_view(template_name='logout/logout.html', next_page='index'),
         name='logout'),
]