addohm
addohm

Reputation: 2455

Django NoReverseMatch on URL with parameter

I'm having some trouble with an extremely simple form view that posts a single value into the redirect view. Both views work by themselves. It is only this particular view that fails when the form is submitted.

views.py

def hsk_select(request, username=None):
    template_name = 'tests/hsklevelselect.html'
    if request.method == 'POST':
        form = HskLevelSelectForm(request.POST)
        if form.is_valid():
            level = form.cleaned_data['level']
            return redirect('tests:hsktest', level=level)
    else:
        form = HskLevelSelectForm()
    context = {
        'form': form,
        'username': username,
    }
    return render(request, template_name, context)

forms.py

class HskLevelSelectForm(forms.Form):
    level = forms.ChoiceField(choices=[(x, x) for x in range(1, 7)])

app/urls.py

from django.urls import path

from . import views

app_name = 'tests'

urlpatterns = [
    path('duolingo/', views.duolingo_test, name='duotest'),
    path('hsk/', views.hsk_select, name='hskselect'),
    path('hsk/<int:level>/', views.hsk_test, name='hsktest'),
]

project/urls.py

from django.urls import path

from . import views

app_name = 'main'

urlpatterns = [
    path('', views.enteruser, name='enteruser'),
    path('success/', views.success, name='success'),
    path('<str:username>/', views.home, name='home'),
]

Traceback

Environment:


Request Method: POST Request URL:
http://duotool.website.net/username/test/hsk/

Django Version: 2.1.5 Python Version: 3.5.2 Installed Applications:
['rest_framework',  'debug_toolbar',  'django.contrib.admin', 
'django.contrib.auth',  'django.contrib.contenttypes', 
'django.contrib.sessions',  'django.contrib.messages', 
'django.contrib.staticfiles',  'main',  'tests',  'widget_tweaks']
Installed Middleware:
['debug_toolbar.middleware.DebugToolbarMiddleware', 
'django.middleware.security.SecurityMiddleware', 
django.contrib.sessions.middleware.SessionMiddleware', 
'django.middleware.common.CommonMiddleware', 
'django.middleware.csrf.CsrfViewMiddleware', 
'django.contrib.auth.middleware.AuthenticationMiddleware', 
'django.contrib.messages.middleware.MessageMiddleware', 
'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback:

File
"/var/www/django/duotool.website.net/venv/lib/python3.5/site-packages/django/core/handlers/exception.py"
in inner
  34.             response = get_response(request)

File
"/var/www/django/duotool.website.net/venv/lib/python3.5/site-packages/django/core/handlers/base.py"
in _get_response
  126.                 response = self.process_exception_by_middleware(e, request)

File
"/var/www/django/duotool.website.net/venv/lib/python3.5/site-packages/django/core/handlers/base.py"
in _get_response
  124.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/var/www/django/duotool.website.net/duotool/tests/views.py" in hsk_select
  132.             return redirect('tests:hsktest', level=level)

File
"/var/www/django/duotool.website.net/venv/lib/python3.5/site-packages/django/shortcuts.py"
in redirect
  58.     return redirect_class(resolve_url(to, *args, **kwargs))

File
"/var/www/django/duotool.website.net/venv/lib/python3.5/site-packages/django/shortcuts.py"
in resolve_url
  148.         return reverse(to, args=args, kwargs=kwargs)

File
"/var/www/django/duotool.website.net/venv/lib/python3.5/site-packages/django/urls/base.py"
in reverse
  90.     return iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs))

File
"/var/www/django/duotool.website.net/venv/lib/python3.5/site-packages/django/urls/resolvers.py"
in _reverse_with_prefix
  622.         raise NoReverseMatch(msg)

Exception Type: NoReverseMatch at /username/test/hsk/ Exception Value:
Reverse for 'hsktest' with keyword arguments '{'level': '1'}' not found. 1 pattern(s) tried:
['(?P<username>[^/]+)\\/test\\/hsk\\/(?P<level>[0-9]+)\\/$']

I'm really not sure what the heck is going on here. I've done far more complicated forms than this. >.< What am I blatantly missing here?

Upvotes: 0

Views: 427

Answers (2)

Alasdair
Alasdair

Reputation: 308849

You haven't showed how you are including app/urls.py in your project's URLs, but the traceback shows that the full URL pattern includes the username:

'(?P<username>[^/]+)\\/test\\/hsk\\/(?P<level>[0-9]+)\\/$'

Therefore you need to include the username when you reverse the URL

redirect('tests:hsktest', username=request.user.username, level=level)

Since the view has username=None as a default, you'll need to consider what you do in this case.

Upvotes: 1

Amine Messaoudi
Amine Messaoudi

Reputation: 2279

Try this :

urlpatterns = [
    path('duolingo/', views.duolingo_test, name='duotest'),
    path('hsk', views.hsk_select, name='hskselect'), # remove slash to distinguish the other url
    path('hsk/<int:level>/', views.hsk_test, name='hsktest'),
]

Upvotes: 0

Related Questions