63

Caught an exception while rendering:

Reverse for 'products.views.'filter_by_led' with arguments '()' and keyword arguments '{}' not found.

I was able to successfully import products.views.filter_by_led from the shell and it worked so the path should be correct.

Here is the urls.py:

(r'^led-tv/$', filter_by_led ),

This is where the error is being generated:

href="{% url products.views.filter_by_led %}">

Which I can't understand because this works fine from the same file:

{% url products.views.lcd_screen_size screen_size=50 %}

Here is the function definition:

def filter_by_led(request):

I don't understand why Django would think that the function would not be able to find the Reverse for that function.

I deleted all the *.pyc files and restarted Apache.

What am I doing wrong?

Foo Bar
  • 147
  • 2
  • 10
BryanWheelock
  • 12,146
  • 18
  • 64
  • 109
  • can you show both lcd_screen_size and filter_by_led url definitions ? – Djangonaut Dec 03 '09 at 19:56
  • 1
    since reverse worked in the shell... it's probably something else causing the problem. I've gotten some pretty weird reverse errors, it kind of seems like ANY bad url definition ANYWHERE in your project can mess the whole thing up :/ – Jiaaro Dec 04 '09 at 00:10

7 Answers7

57

There are 3 things I can think of off the top of my head:

  1. Just used named urls, it's more robust and maintainable anyway
  2. Try using django.core.urlresolvers.reverse at the command line for a (possibly) better error

    >>> from django.core.urlresolvers import reverse
    >>> reverse('products.views.filter_by_led')
    
  3. Check to see if you have more than one url that points to that view

user8193706
  • 2,387
  • 2
  • 8
  • 12
Jiaaro
  • 74,485
  • 42
  • 169
  • 190
  • reverse seems to work fine from the shell: >>> from django.core.urlresolvers import reverse >>> reverse('products.views.filter_by_led') '/reviews/led/' – BryanWheelock Dec 03 '09 at 22:31
  • 1
    I also tried using names urls and I got the same type of error: Caught an exception while rendering: Reverse for 'ledtvfilter' with arguments '()' and keyword arguments '{}' not found. – BryanWheelock Dec 03 '09 at 22:46
  • if reverse worked in the shell then that probably isn't what's causing the error – Jiaaro Dec 04 '09 at 00:07
  • named urls simply served my purpose too :) – Hafiz Jun 20 '12 at 07:51
  • 1
    @Jiaaro Also we can add number 4) The url, views, and reverse might be okay, but if the html has a bad `{% url %}` then we also get this error – mgPePe Oct 06 '13 at 11:13
  • How do you use `django.core.urlresolvers.reverse` at the command line? Can you explain? I have the command line open in the directory of the project, but it doesn't recognize my commands (which I am borrowing from the Django-Project page). – CodyBugstein Mar 02 '14 at 15:23
  • @imray that's a whole question and answer of it's own, you should post it as a new question :) – Jiaaro Mar 02 '14 at 22:20
  • http://stackoverflow.com/questions/22143265/how-to-use-reverse-from-django-core-urlresolvers-reverse – CodyBugstein Mar 03 '14 at 09:44
  • 1
    from django.urls import reverse <- this worked for me – Nikhil Bhardwaj Jan 19 '21 at 14:14
37

Shell calls to reverse (as mentioned above) are very good to debug these problems, but there are two critical conditions:

  • you must supply arguments that matches whatever arguments the view needs,
  • these arguments must match regexp patterns.

Yes, it's logical. Yes, it's also confusing because reverse will only throw the exception and won't give you any further hints.

An example of URL pattern:

url(r'^cookies/(?P<hostname>[^/]+)/(?P<url_id>\d+)/$', 'register_site.views.show_cookies', name='show_cookies'),

And then what happens in shell:

>>> from register_site.views import show_cookies
>>> reverse(show_cookies)
NoReverseMatch: Reverse for 'register_site.views.show_cookies' with arguments '()' and keyword arguments '{}' not found.

It doesn't work because I supplied no arguments.

>>> reverse('show_cookies', kwargs={'url_id':123,'hostname': 'aaa'})
'/cookies/aaa/123'

Now it worked, but...

>>> reverse('show_cookies', kwargs={'url_id':'x','hostname': 'www.dupa.com'})
NoReverseMatch: Reverse for 'show_cookies' with arguments '()' and keyword arguments '{'url_id': 'x', 'hostname': 'www.dupa.com'}' not found.

Now it didn't work because url_id didn't match the regexp (expected numeric, supplied string).

You can use reverse with both positional arguments and keyword arguments. The syntax is:

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

As it comes to the url template tag, there's funny thing about it. Django documentation gives example of using quoted view name:

{% url 'news.views.year_archive' yearvar %}

So I used it in a similar way in my HTML template:

{% url 'show_cookies' hostname=u.hostname url_id=u.pk %}

But this didn't work for me. But the exception message gave me a hint of what could be wrong - note the double single quotes around view name:

Reverse for ''show_cookies'' with arguments...

It started to work when I removed the quotes:

{% url show_cookies hostname=u.hostname url_id=u.pk %}

And this is confusing.

kravietz
  • 10,667
  • 2
  • 35
  • 27
  • 1
    I used a url (r'^candidate-verifymobile/$, views.VerifyMobile.as_view(), name='verify-mobile'), but still when I use reverse it gives the same error in this case I do not have any keyword argument in the url. – Arpit Goyal May 25 '15 at 06:02
  • in situations where sometimes i will have an argument and other times i will not, do i need to then create two separate view functions and two separate urls in my **urls.py**? using your example imagine sometimes `u.pk` is a number other times it is None. but in your template you are using `{% url 'show_cookies' url_id=u.pk %}`. i tried adding `{% if u.pk == None %} show error message {%else%} {% url 'show_cookies' url_id=u.pk %} {%endif%}` but i still get a NoReverseMatch exception. – Deven Feb 23 '18 at 17:57
  • 2
    www.dupa.com _________ – Tomasz Garbus Apr 04 '20 at 18:46
  • 1
    For 7 long years I hoped someone finally notices – kravietz Apr 06 '20 at 20:31
12

You need single quotes around the view name

{% url 'viewname' %}

instead of

{% url viewname %}
Charlie
  • 8,530
  • 2
  • 55
  • 53
4

I had a similar problem and the solution was in the right use of the '$' (end-of-string) character:

My main url.py looked like this (notice the $ character):

urlpatterns = [
url(r'^admin/', include(admin.site.urls )),
url(r'^$', include('card_purchase.urls' )),
]

and my url.py for my card_purchases app said:

urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^purchase/$', views.purchase_detail, name='purchase')
]

I used the '$' twice. So a simple change worked:

urlpatterns = [
url(r'^admin/', include(admin.site.urls )),
url(r'^cp/', include('card_purchase.urls' )),
]

Notice the change in the second url! My url.py for my card_purchases app looks like this:

urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^purchase/$', views.purchase_detail, name='purchase')
]

Apart from this, I can confirm that quotes around named urls are crucial!

DJGrandpaJ
  • 571
  • 3
  • 7
  • 20
Hendrik F
  • 3,690
  • 3
  • 21
  • 24
  • Thanks a lot. Spent an hour debugging the issue. Your solution was just what I was missing. – v01d Dec 22 '15 at 12:25
2

In case it helps someone, I had a similar issue and the error was because of two reasons:

  1. Not using the app's namespace before the url name

    {% url 'app_name:url_name' %}
    
  2. Missing single quotes around the url name (as pointed out here by Charlie)

Anupam
  • 14,950
  • 19
  • 67
  • 94
0

I don't think you need the trailing slash in the URL entry. Ie, put this instead:

(r'^led-tv$', filter_by_led ),

This is assuming you have trailing slashes enabled, which is the default.

Chase Seibert
  • 15,703
  • 8
  • 51
  • 58
  • 1
    it shouldn't matter, but if you want a trailing slash in the url, it should be there (All my `urls.py` files have the trailing slash) – Jiaaro Dec 03 '09 at 21:12
0
{% url 'polls:create' poll.id %}
Raghu
  • 31
  • 7