Reputation: 5609
Suppose I want to pass the username in the url:
username = '[email protected]'
So in the urls, its like this:
url(r'(?P<user_name>\w+)/$', 'user_related.views.profile', name='profile'),
And to fetch that user, in the views.py:
def profile(request, user_name):
user = User.objects.get(username=user_name)
return render(request, 'user_profile.html', {'user':user})
But I get an error:
User matching query does not exist.
Because django automatically converts @
into %40
. How can I pass the actual username
to the view? Please help me solve this problem. Thank you!
Upvotes: 3
Views: 7968
Reputation: 61
The existing answer is missing a couple things, but I don't have enough rep to comment or edit it. Here is a working solution:
For function based views:
In views.py
:
# this is incorrect for current versions of Django in the other answer
from urllib.parse import unquote
def profile(request, user_name):
user = User.objects.get(username=unquote(user_name))
return render(request, 'user_profile.html', {'user':user})
Then, in urls.py
, we can skip regex altogether:
from django.urls import path
urlpatterns = [
path('users/<str:user_name>/', views.profile, name='profile'),
# ... put more urls here...
]
That's pretty much it for function based views. But I am using class based views, which look a tiny bit different. Here is what I did to get this working with class based views:
In views.py
:
from urllib.parse import unquote
from django.views.generic import DetailView
class Profile(DetailView):
"""Display the user's profile"""
template_name = 'user_profile.html'
model = User
def dispatch(self, request, *args, **kwargs):
self.username = kwargs['user_name']
return super().dispatch(request, *args, **kwargs)
def get_object(self, *args, **kwargs):
try:
return User.objects.get(username=unquote(self.username))
except:
raise Http404
And when using class based views, your urls.py
:
from django.urls import path
urlpatterns = [
path('users/<str:user_name>/', views.Profile.as_view(), name='profile'),
# ... put more urls here...
]
Upvotes: 3
Reputation: 1807
Specify the string by using w
url(r'^url_name/(?P<param_name>[\w\@%-+]+)/$',url_method,name='end_point_name')
Upvotes: 0
Reputation: 45595
Use unquote function from standard urllib
module:
from urllib import unquote
user = User.objects.get(username=unquote(user_name))
BTW, as far as I understand regex in your url() should be [\w@%.]+
. Plain \w+
do not match [email protected]
and kakar%40gmail.com
.
Upvotes: 7