After a user logs into my app, I would like to redirect the person to their profile.
However, I keep getting this error:
TypeError at /app/url/username/
profile() got an unexpected keyword argument 'username'
Here is the model:
class UserProfile(models.Model):
user = models.OneToOneField(User)
profile_picture = models.ImageField(upload_to='profile_images', blank = True)
def __str__(self):
return self.user.username
Here is the view where the user will log in and that will then redirect the user to the profile:
def user_login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(username=username, password=password)
if user:
if user.is_active:
login(request, user)
url = reverse('profile', kwargs={'username': username})
return redirect(url)
else:
return HttpResponse("Please login.")
else:
print("Invalid login details: {0}, {1}".format(username, password))
return HttpResponse("Invalid login details supplied.")
else:
return render(request, 'reviews/login.html', {})
Here is the view for the user profile:
@login_required
def profile(request, user):
user = UserProfile.objects.get(user = request.user)
return render(request, 'reviews/profile.html', {'username':username})
Here is the url pattern:
url(r'^profile/(?P<username>\w+)/$', views.profile, name='profile')
Can someone tell me how to redirect the logged user to their profile?
Tried both approaches suggested so far. I received this error for both of them:
UserProfile matching query does not exist.
Here is the traceback:
Environment:
Request Method: GET
Request URL: http://localhost:8000/app/profile/username/
Django Version: 1.8.3
Python Version: 3.4.3
Installed Applications:
('grappelli',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'reviews',
'compressor',
'cloudinary')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware')
Traceback:
File "/var/www/nurse/lib/python3.4/site- packages/django/core/handlers/base.py" in get_response
132. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/var/www/nurse/lib/python3.4/site- packages/django/contrib/auth/decorators.py" in _wrapped_view
22. return view_func(request, *args, **kwargs)
File "/var/www/nurse/nurseapp/reviews/views.py" in profile
165. user=UserProfile.objects.get(user = request.user)
File "/var/www/nurse/lib/python3.4/site-packages/django/db/models/manager.py" in manager_method 127. return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/var/www/nurse/lib/python3.4/site-packages/django/db/models/query.py" in get 334. self.model._meta.object_name
Exception Type: DoesNotExist at /app/profile/username/
Exception Value: UserProfile matching query does not exist.
I see two possible issues in your code:
First one, in user_login
function when creating url for redirection using reverse()
, you should pass username
value in args
instead of kwargs
:
url = reverse('profile', args=(username,))
Second thing, it seems you named the parameter in profile url as username
which means it will be passed into corresponding view function with the same name so you should rename user
as username
in view and update your logic as follows:
@login_required
def profile(request, username):
p = UserProfile.objects.get(user__username=username)
return render(request, 'reviews/profile.html',
{'username': username, 'user': p.user, 'profile': p})
Please note that, for each User
object, there must be one UserProfile
corresponding to it. If you don't create a UserProfile
object after new user signs up, you can try sending User
object to your template instead:
@login_required
def profile(request, username):
user = User.objects.get(username=username)
return render(request, 'reviews/profile.html',
{'username': username, 'user': user})
It is a bad practice but, in user_login
view, you can try creating UserProfile
if not exists once user logs in:
def user_login(request):
...
user = authenticate(username=username, password=password)
if user:
if user.is_active:
UserProfile.objects.get_or_create(user=user)
...
...