NoReverseMatch Exception in django named group url - python

I am new to django and playing with urls and stuck on this problem,
I have a view in my views.py which reverse url to a different view
def index(request):
username = request.session.get('username')
if username is None:
return HttpResponseRedirect(reverse('login_page'))
#return HttpResponse("Testing view session not found")
else:
return HttpResponseRedirect(reverse('profile_page', kwargs = {'username': username,}))
#return HttpResponse("Testing view " + username)
now when code will reach to else block since username is not None, so here is my URLconf
urlpatterns = patterns('',
url(r'(?P<username>^)', views.profile, name = "profile_page"),)
So in simple words I am calling profile_page url which is using a named parameter username and I am passing the same from kwargs, but I am getting NoReverseMatch with Exception Message:
Reverse for 'profile_page' with arguments '()' and keyword arguments '{'username': 'dheerendra'}' not found. 1 pattern(s) tried: ['user/(?P^)']

To construct a profile_page URL, it requires a username to be fully filled out. You're calling reverse('profile_page') without passing username in the kwargs.

Two things:
You've given the url a named group username but you haven't actually given a regular expression for the named group. You want your username regular expression to match a varying length username so you need:
url(r'?P<username>\w+)/$', views.profile, name="profile_page"),
where \w+ is the regular expression
Secondly, as you will see from the examlpe above, you need to terminate the regular expression with a $ so that urls such as /myusername/otherstring/ don't incorrectly get matched

Related

Django reverse and redirect after ajax request returns django.urls.exceptions.NoReverseMatch

I call a specific url from and ajax function which will calls the respective view function. In view function I want to redirect the page by calling another view (because I can't render after ajax request).
Here are my urls:
urlpatterns = [
url(r'^$', views.search, name='search'),
url(r'^search_result/.+$', views.search_result, name='search_result'),
url(r'^new_search_result/$',
views.new_search_result,
kwargs={'selected': '', 'keyword': ''},
name='new_search_result')
]
And here is the search_result view:
#csrf_exempt
def search_result(request):
keyword = request.POST.get('keyword')
selected = request.POST.get('selected')
url = reverse('new_search_result',
kwargs={'keyword': keyword,
'selected': selected})
return HttpResponseRedirect(url)
# return render(request, 'SearchEngine/search_result.html', {'all_results': result})
And here is the new_search_result view:
def new_search_result(request, selected={}, keyword=''):
# code blocks
But in consul I get this error:
django.urls.exceptions.NoReverseMatch: Reverse for 'new_search_result' with keyword arguments '{'selected': '{"PANTHER":"ftp.pantherdb.org","Pasteur Insitute":"ftp.pasteur.fr","Rat Genome Database":"ftp.rgd.mcw.edu"}', 'keyword': 'dfasdf'}' not found. 1 pattern(s) tried: ['searchengine/new_search_result/$']
[22/Jul/2017 12:52:12] "POST /searchengine/search_result/dfasdf HTTP/1.1" 500 16814
The kwargs argument to url
The extra kwargs argument you provide to the call to url allows you to define extra parameters that are then passed on to the view. They do not define extra arguments that are provided when fetching the url - the call to reverse does not know about these extra arguments, the call to reverse only knows about the arguments defined in the url pattern.
So if you have:
urlpatterns = [
url(r'^blog/(?P<year>[0-9]{4})/$', myview,
kwargs={'foo': 'bar'}),
]
This means that when your url is fetched as blog/1111 then view myview is invoked with two parameters: year with value 1111 and foo with value bar.
Only the view sees the extra argument foo - it is not in the url, and it is not provided to the reverse function. The kwargs argument of the reverse function actually refers to the arguments defined in the url pattern.
Passing parameters to a view
So looking at what you're trying to achieve: you want to redirect the user's browser to a different URL, such that the resulting view will have access to the keyword and selected parameters.
If you wanted that data to be hidden from the user, you would have to store it in the session. Assuming this is not the case you have three ways to pass parameters to a view: via GET parameters, via POST data and view the url. In your case as you're redirecting to another page, you can't use a POST request. You could use the url but for a search page I would think the best option would be to use GET parameters.
So in your search_result view you could add a query string to the URL ie. ?keyword=...&selected=.... For example:
import urllib
#csrf_exempt
def search_result(request):
args = {
'keyword': request.POST.get('keyword'),
'selected': request.POST.get('selected')
}
url = '%s?%s' % (
reverse('new_search_result'),
urllib.urlencode(args)
)
return HttpResponseRedirect(url)
And your new_search_result view would read those from the request:
def new_search_result(request):
selected = request.GET.get('selected')
keyword = request.GET.get('keyword')
# ...

Django: reverse() does not find view with args/kwargs given

There are a few posts related to my problem. However, none seems to solve the following issue:
I have defined urls in myapp/urls.py:
app_name = "myapp"
urlpatterns=[
url(r'^$', views.index, name="index"),
url(r'^adduser/$', views.addUser, name="adduser"),
]
and corresponding views in myapp/views.py:
def index(request, status_msg=None, error_msg=None):
return HttpResponse(render(request, "myapp/index.html",
context={"error_message":error_msg, "status_message":status_msg}))
def addUser(request):
try:
uname=request.POST["user_name"]
except KeyError:
url = reverse("myapp:index", args=(None, "No user name specified."))
return HttpResponseRedirect(url)
# ... adding user to db ...
url = reverse("myapp:index", args=("Added user '%s'"%uname,))
return HttpResponseRedirect(url)
Either variant of passing arguments to index() from the redirect in addUser() yields an error of the kind
Reverse for 'index' with arguments '(None, u'No user name specified.')' not found. 1 pattern(s) tried: [u'myapp/$']
I don't get what I'm doing wrong here. Seems the index view is found but not recognized to allow any arguments aside the request?
Using kwargs instead of args does not help, either.
Any suggestions are highly appreciated. Thanks already!
Your URL doesn't seem to support arguments (i.e captured groups in the regex). Therefore you should be using just:
reverse("myapp:index")
Check the docs for the reverse() function here.

How do I pass parameters via url in django?

I am trying to pass a parameter to my view, but I keep getting this error:
NoReverseMatch at /pay/how
Reverse for 'pay_summary' with arguments '(False,)' and keyword arguments '{}' not found. 1 pattern(s) tried: ['pay/summary/$']
/pay/how is the current view that I'm at. (that is the current template that that view is returning).
urls.py
url(r'^pay/summary/$', views.pay_summary, name='pay_summary')
views.py
def pay_summary(req, option):
if option:
#do something
else:
#do something else
....
template
my link
EDIT
I want the view should accept a POST request, not GET.
To add to the accepted answer, in Django 2.0 the url syntax has changed:
path('<int:key_id>/', views.myview, name='myname')
Or with regular expressions:
re_path(r'^(?P<key_id>[0-9])/$', views.myview, name='myname')
You need to define a variable on the url. For example:
url(r'^pay/summary/(?P<value>\d+)/$', views.pay_summary, name='pay_summary')),
In this case you would be able to call pay/summary/0
It could be a string true/false by replacing \d+ to \s+, but you would need to interpret the string, which is not the best.
You can then use:
my link

Django HttpResponseRedirect(reverse('url')) Returns NoReverseMatch Error

I have this tag <a href = '/mysite/goto_home/Yax/'>Yax</a>
I want if a user clicks on it, he/she should be redirected to this URL:
url(r'^user/(?P<user_id>\d+)/(?P<user_name>[-\w]+)/$', views.user_profile, name='user_profile')
But it's giving me NoReverseMatch at /mysite/goto_home/Yax/
Reverse for 'user_profile' with arguments '()' and keyword arguments '{'user_id': 2, 'user_name': u'Mokwa'}' not found. 1 pattern(s) tried: [u'mysite/user/(?P<user_id>\\d+)/(?P<user_name>[-\\w]+)/$']
Views.py:
def profile(request, user_name):
try:
user = Users.objects.get(username = user_name)
except Users.DoesNotExist:
user = none
if user is not None:
return HttpResponseRedirect(reverse('mysite:user_profile', kwargs={'user_id': int(user.id), 'user_name':user.name}))
def user_profile(request, user_id, user_name):
pass
How can I solve this?
You used "mysite:user_profile" for your reverse call, but the URL is not in a namespace. You should either use just "user_profile" or set a namespace for the URLs wrapped in a call to include.
Namespaces are explained in greater detail here. https://docs.djangoproject.com/en/dev/topics/http/urls/#url-namespaces

using HttpResponseRedirect

In one of my view function, under certain condition I want to redirect to another URL.
So I am doing
return HttpResponseRedirect(reverse(next_view, kwargs={'name': name1}))
Now I have another view function like
def next_view(request, name):
I also put following line in relevant urls.py file
from wherever import next_view
urlpatterns = patterns("",
url(r"^next_view/(?P<name>w+)/", next_view, name="next_view"),
)
This does not work, I get
Reverse for 'next_view' with arguments '()' and keyword arguments '{'name': u'test'}' not found.
I'm guessing that the regex isn't matching properly. How about:
r"^next_view/(?P<name>\w+)/"
Note the backslash before the 'w'.
For urls.py you want to add the backslash before the w+ and also add a $ sign at then end of the URL so that any other URL's joined onto this will be accepted:
urlpatterns = patterns("",
url(r"^next_view/(?P<name>\w+)/$", next_view, name="next_view"),
)
For views.py you want to add parenthesis around your view name:
def example_view(self):
# view code
return HttpResponseRedirect(reverse('next_view', kwargs={'name': name1}))

Categories

Resources