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()
.
reverse
with function referencesI’m using the Django trunk, revision 9092.
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.
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.
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.
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'),
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With