arcee123
arcee123

Reputation: 211

django working with url parameters in views and templates

I am using Django 2.1+, with Python 3.6+.

in my urls.py, I have this url:

url('^member/(?P<username>[\w\-]+)/$', views.Member, name='member_data'),

Alone this works:

However from both the view:

def login(request):
    email = request.POST['email']
    password = request.POST['password']
    username = User.objects.get(email=email)
    user = authenticate(request, username=username.username, password=password)
    if user is not None:
        auth_login(request, user)
        # Redirect to a success page.
        return reverse('member_data', {'username': username.username})
    else:
        # Return an 'invalid login' error message.
        return redirect('login_page', {'error': 1})

and from the template (of note, this is a hardcode username to attempt to get the template the work):

<a href="{% url 'member_data' username='cheng' %}"><i class="ion ion-person"></i>My Service Record</a>

Results in a bad parameter error, in which I cannot resolve. As such, Any wisdom here would be greatly appreciated. Is there a way this is supposed to read for both links?

the error that I'm starting with is from the login attempt:

Environment:


Request Method: POST
Request URL: http://127.0.0.1:8000/login_action/

Django Version: 2.1b1
Python Version: 3.6.3
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'mptt',
 'svcrecord']
Installed Middleware:
['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 "/Users/sinistersparrow/venv/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner
  34.             response = get_response(request)

File "/Users/sinistersparrow/venv/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  126.                 response = self.process_exception_by_middleware(e, request)

File "/Users/sinistersparrow/venv/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  124.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/Users/sinistersparrow/PycharmProjects/ifthqcom/svcrecord/views.py" in login
  36.         return reverse('member_data', {'username': username.username})

File "/Users/sinistersparrow/venv/lib/python3.6/site-packages/django/urls/base.py" in reverse
  30.     resolver = get_resolver(urlconf)

Exception Type: TypeError at /login_action/
Exception Value: unhashable type: 'dict'

And this is the error when going to the page directly:

UPDATE #1...

the template seems to be working now. still dealing with the view. Thanks

Upvotes: 1

Views: 519

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476537

The reverse(..) [Django-doc] parameter has as signature:

reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None

Now it is of course the kwargs we are interested in. But with a call like:

return reverse('member_data', {'username': username.username})

we actually pass the dictionary to the urlconf parameter, and this does not expect a dictionary.

We can however pass it to the kwargs parameter, by passing it to a named parameter, like:

return reverse('member_data', kwargs={'username': username.username}))

You furthermore need to wrap it in a redirect(..) to redirect the browser to this URL:

return redirect(reverse('member_data', kwargs={'username': username.username})))

Django however accepts that the redirect(..) contains a view(name) and parameters directly as well, like:

return redirect('member_data', username=username.username)

Upvotes: 1

Related Questions