Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I successfully pass a function reference to Django’s reverse() function?

Tags:

python

django

I’ve got a brand new Django project. I’ve added one minimal view function to views.py, and one URL pattern to urls.py, passing the view by function reference instead of a string:

# urls.py
# -------

# coding=utf-8

from django.conf.urls.defaults import *

from myapp import views


urlpatterns = patterns('',
    url(r'^myview/$', views.myview),
)


# views.py
----------

# coding=utf-8

from django.http import HttpResponse


def myview(request):
    return HttpResponse('MYVIEW LOL',  content_type="text/plain")

I’m trying to use reverse() to get the URL, by passing it a function reference. But I’m not getting a match, despite confirming that the view function I’m passing to reverse is the exact same view function I put in the URL pattern:

>>> from django.core.urlresolvers import reverse
>>> import urls
>>> from myapp import views

>>> urls.urlpatterns[0].callback is views.myview
True

>>> reverse(views.myview)
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/Library/Python/2.5/site-packages/django/core/urlresolvers.py", line 254, in reverse
    *args, **kwargs)))
  File "/Library/Python/2.5/site-packages/django/core/urlresolvers.py", line 243, in reverse
    "arguments '%s' not found." % (lookup_view, args, kwargs))
NoReverseMatch: Reverse for '<function myview at 0x6fe6b0>' with arguments '()' and keyword arguments '{}' not found.

As far as I can tell from the documentation, function references should be fine in both the URL pattern and reverse().

  • URL patterns with function references
  • reverse with function references

I’m using the Django trunk, revision 9092.

like image 581
Paul D. Waite Avatar asked Sep 28 '08 19:09

Paul D. Waite


People also ask

What does reverse () do in Django?

the reverse function allows to retrieve url details from url's.py file through the name value provided there. This is the major use of reverse function in Django. The redirect variable is the variable here which will have the reversed value. So the reversed url value will be placed here.

What does it mean to reverse a url?

Just in case you do not know why it is called reverse : It takes an input of a url name and gives the actual url, which is reverse to having a url first and then give it a name.

What is reverse and reverse lazy in Django?

Reverse_lazy is, as the name implies, a lazy implementation of the reverse URL resolver. Unlike the traditional reverse function, reverse_lazy won't execute until the value is needed. It is useful because it prevent Reverse Not Found exceptions when working with URLs that may not be immediately known.


1 Answers

Got it!! The problem is that some of the imports are of myproject.myapp.views, and some are just of myapp.views. This is confusing the Python module system enough that it no longer detects the functions as the same object. This is because your main settings.py probably has a line like:

ROOT_URLCONF = `myproject.urls`

To solve this, try using the full import in your shell session:

>>> from django.core.urlresolvers import reverse
>>> from myproject.myapp import views
>>> reverse(views.myview)
'/myview/'

Here's a log of the debugging session, for any interested future readers:

>>> from django.core import urlresolvers
>>> from myapp import myview
>>> urlresolvers.get_resolver (None).reverse_dict
{None: ([(u'myview/', [])], 'myview/$'), <function myview at 0x845d17c>: ([(u'myview/', [])], 'myview/$')}
>>> v1 = urlresolvers.get_resolver (None).reverse_dict.items ()[1][0]
>>> reverse(v1)
'/myview/'
>>> v1 is myview
False
>>> v1.__module__
'testproject.myapp.views'
>>> myview.__module__
'myapp.views'

What happens if you change the URL match to be r'^myview/$'?


Have you tried it with the view name? Something like reverse ('myapp.myview')?

Is urls.py the root URLconf, or in the myapp application? There needs to be a full path from the root to a view for it to be resolved. If that's myproject/myapp/urls.py, then in myproject/urls.py you'll need code like this:

from django.conf.urls.defaults import patterns
urlpatterns = patterns ('',
    (r'^/', 'myapp.urls'),
)
like image 163
John Millikin Avatar answered Oct 26 '22 21:10

John Millikin