NoReverseMatch exception - redirect with keyword arguments - django

I am getting a NoReverseMatch error when trying to use Django's redirect, and cannot figure out what I am doing wrong.
In views:
def addConjugatedForm(request):
#update database
return redirect('findConjugatedForms', chapter=ch.chapter, verse=verse.verse, book=b.name)
def findConjugatedForms(request, book, chapter, verse):
#return a view
In urls.py:
url(r'^findConjugatedForms/(?P<book>\w+)/(?P<chapter>\d+)/(?P<verse>\d+)/', 'findConjugatedForms'),
The url works as a url, i.e. "...findConjugatedForms/Romans/3/24" returns a page. But when a form on that page is submitted, it won't redirect back.
I have named arguments in my url (which seems to be the common problem in other questions on Stack Overflow) and the values of the kwargs seem to be correct.
Reverse for 'findConjugatedForms' with arguments '()' and keyword arguments '{'chapter': 3, 'verse': 24, 'book': u'Romans'}' not found. 0 pattern(s) tried: []
What am I missing?

redirect uses reverse internally. You need to define a viewname for the url, or use a Python path or pass a callable object:
url(r'^findConjugatedForms/(?P<book>\w+)/(?P<chapter>\d+)/(?P<verse>\d+)/',
'findConjugatedForms',
name='findConjugatedForms') # Define a name
Besides, add a suffix '$' into the pattern to prevent the url from matching other urls that starts with findConjugatedForms/book/chapter/verse/

Related

Django NoReverseMatch at

I have the following URLs:
url(r'^%sdform/' %(URLPREFIX), pv.dform, name='dform'),
url(r'^%sform/(P?<growl>.*)/' %(URLPREFIX), pv.dform, name='dform'),
The view code:
def dform(request, growl = None) is the method signature
The redirect code:
msg = 'test'
return redirect('dform', growl=msg)
Any idea why I get that error? I'm sending the right parameter to the right view method with the right argument name and all that.
EDIT:
Based on the answer below, I tried:
url(r'^%sdform/(P?<growl>.*)/' %(URLPREFIX), pv.dform, name='dform_message')
And changed the redirect to:
return redirect('dform_message', growl='Updated Settings')
I still get NoReverseMatch
I think your problem is that you shall not use the same names for different urls (django docu).

URL with args does not reverse

I have the following url:
urlpatterns += patterns('app_common.views_settings',
url(r'([\w-]+)/(\d+)/settings/$', 'settings', name="configuration_homepage"),
url(r'(?P<short_name>[\w-]+)/(?P<product_id>\d+)/settings/modify/(?P<sim_id>\d+)/$', 'modify_sim', name="modify_sim"),
)
urlpatterns += patterns('app_common.views_operator',
url(r'^operator/$', 'choose_operator', name="choose_operator"),
url(r'^(?P<short_name>[\w-]+)/project/$', 'choose_project', name="choose_project"),
url(r'([\w-]+)/(\d+)/$', 'set_product', name="set_product"),
url(r'^(?P<short_name>[\w-]+)/$', 'set_operator', name="set_operator"),
)
I tried to reverse configuration homepage using:
url = reverse('configuration_homepage', kwargs={short_name, product_id})
return HttpResponseRedirect(url)
Some times it works, but other times if failed with this issue (short_name=OCI and product_id=1)
Exception Type: NoReverseMatch
Exception Value: Reverse for 'configuration_homepage' with arguments '(u'1', u'OCI')' and keyword arguments '{}' not found.
If you guys detect something wrong in my code fell free to tell me... I tried to give name to variable but urls are not found in that case.
Use args instead of kwargs,
url = reverse('configuration_homepage', args=[short_name, product_id])
Your kwargs is wrong, you are passing a set() instead of a dict()
What you (probably) want is:
url = reverse('configuration_homepage',
kwargs={short_name: short_name, product_id: product_id})
This is one of the many reasons why I prefer dict(a=1, b=2) over {a:1, b:2} when possible,

Django URL Conf For Keyword Argument

What's wrong with the URL conf below:
url(
r'^outgoing-recommendations(?P<entry>\w+)/$',
login_required(outgoing_messages),
name='outgoing-recommendations',
),
Here is the invocation:
return redirect('outgoing-recommendations', kwargs={'entry':'outgoing'})
Here is the view function:
def outgoing_messages(request,entry):
user = User.objects.get(pk=request.session['user_id'])
I'm getting the error below:
Reverse for 'outgoing-recommendations' with arguments '()' and keyword arguments '{'kwargs': {'entry': 'outgoing'}}' not found.
The URL should look like this
url(r'^outgoing-recommendations/(?P<entry>\w+)/$',login_required(outgoing_messages), name='outgoing-recommendations'),
So you forgot your / on outgoing-recommendations.
Also you should call your redirect like this
return redirect('outgoing-recommendations', entry='outgoing')
and leave off the kwargs={} part, because what's happening is that you're trying to send in the keyworded arguments kwargs with it's nested kwargs.
But what I think you actually want is this
return redirect(reverse('outgoing-recommendations', kwargs={'entry':'outgoing'}))

Reverse for '' with arguments and keyword arguments '' not found

I have following views in my light_shop app:
def order_list(request, error_message):
context = {}
context['type'] = 'order-list'
context['error_message'] = error_message
update_context(request, context, add_order_list=True)
return render(request, 'light_shop/order_list.html', context)
def add_to_list(request, prd_id):
add_product_to_list(request, prd_id)
return HttpResponseRedirect(reverse('light_shop.views.order_list', args=('test_error',)))
and this is urls.py
urlpatterns = patterns('light_shop',
...
url(r'^add-to-list/(?P<prd_id>\d+)/$', 'views.add_to_list'),
url(r'^show-list/()$', 'views.order_list'),
...
)
but I get error: Reverse for 'light_shop.views.order_list' with arguments '('test_error',)' and keyword arguments '{}' not found. in add_to_list second line.
I even test naming parameter in url pattern for order_list. (e.g. url(r'^show-list/(?P<error_message>)$', 'views.order_list') and changing reverse function to reverse('light_shop.views.order_list', kwargs={'error_message':'error_message'})) but again same error is occurred.
I'm using Django 1.5 and I look this page for documantation and I am really confused what is the problem:
https://docs.djangoproject.com/en/1.5/topics/http/urls/
The problem is with the URL pattern
url(r'^show-list/()$', 'views.order_list'),
which seems to be incomplete.
Update it to (Basically, specify a Named Group)
url(r'^show-list/(?P<error_message>[\w_-]+)$', 'views.order_list'),

Can I pass non-URL definition view keyword to a view function when redirecting?

NoReverseMatch at /natrium/script/4c55be7f74312bfd435e4f672e83f44374a046a6aa08729aad6b0b1ab84a8274/
Reverse for 'run_details' with arguments '()' and keyword arguments '{'script_text': u'print "happy"', 'run_id': '6b2f9127071968c099673254fb3efbaf'}' not found.
This is an excerpt of my views.py
run_id = new_run.run_id
if not run_id:
raise AssertionError("bad run id")
# I tried with args=[run_id, clean['script_text']] too
return HttpResponseRedirect(reverse('run_details', kwargs={'run_id':run_id, 'script_text':clean['script_text']}))
which in turns calling this view function
def run_details(request, run_id, script_text):
"""
Displays the details of a given run.
"""
run = Run(run_id)
run.update(request.user)
codebundle = CodeBundle(run.cbid)
codebundle.update(request.user)
return render_response(request, "graphyte/runs/run_script.html",
{'run':run, 'codebundle':codebundle, 'files':run.artifacts, 'bundle':codebundle,
'source_code': script_text
})
Now this is my urls.py. The actual redirect views is in another app (kinda insane, but whatever...).
urlpatterns = patterns("webclient.apps.codebundles.views",
# many.....
url(r"^cb/newfolder/$", 'codebundle_newfolder', name="codebundle_newfolder"),
)
urlpatterns += patterns('webclient.apps.runs.views',
url(r"^run_details/(?P<run_id>\w+)/$", 'run_details', name="run_details"),)
This is getting really nasty for the last three hours. I am not sure what's going on. Can someone help me debug this?
Thanks.
The original plan did not have script_text, and I used args=['run_id'] only. It works. In other words, remove script_text from the two views everything will work.
EDIT
Sorry for the confusion. Script text is just a context variable that I need to pass to the reverse destination, and from there I render my template. The URLs should only display the run_id.
No, you can't really pass an 'extra keyword' to the view function when redirecting. I'll try to explain why.
When you return HttpResponseRedirect, Django returns a response with a 302 status code, and the new location.
HTTP/1.1 302 Found
Location: http://www.example.com/new-url/
Your browser will then usually fetch the new url, but that's a separate request. If your view needs a keyword, it needs to be included in that response somehow, unless you store state in the session. Your two options are
Include the extra keyword in the url:
http://www.example.com/new-url/keyword-value/
Include the extra keyword as a GET parameter
http://www.example.com/new-url/?keyword=keyword-value.
Then in your view, grab the keyword with keyword=request.GET['keyword']. Note that the keyword is no longer a kwarg in the view signature.
A third approach is to stick the keyword into the session before you redirect, then grab it out the session in the redirected view. I would advise against doing this because it's stateful and can cause odd results when users refresh pages etc.
Your run_details url doesn't accept a kwarg named script_text at all -- remove that from your reverse kwargs.