miguelfg
miguelfg

Reputation: 1524

django urlresolve does not resolve

I have tried so many things, and read the docs, other related problems, that i became crazy and blind about this, because it seems clear where the error is, but i can't find it.

My project name: 'observatorio'.

My app name: 'tdcp'

My dir structure like this:

observatorio/
   settings.py
   urls.py
   manage.py
   ...
   tdcp/
       static/
       templates/
       __init__.py
       urls.py
       views.py
       models.py

a bit of my settings.py:

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # Uncomment the next line to enable the admin:
    'django.contrib.admin',
    # Uncomment the next line to enable admin documentation:
    # 'django.contrib.admindocs',
    'core',
    'tdcp',
    'south',
    'django.contrib.humanize',
)
ROOT_URLCONF = 'urls'
# ROOT_URLCONF = 'tdcp.urls'

I wanted to include my app tdcp\urls.py in the project urls.py in order to do things right if i create more apps in the future, and have a more scalable code from the begining. So:

My project urls.py:

from django.conf.urls import patterns, include, url


# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
    url('', include('tdcp.urls', namespace='tdcp')),

    # Uncomment the admin/doc line below to enable admin documentation:
    # url(r'^admin/doc/', include('django.contrib.admindocs.urls')),

    # Uncomment the next line to enable the admin:
    url(r'^admin/', include(admin.site.urls)),
)

My tdcp.urls.py:

from django.conf.urls import patterns, include, url

# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('tdcp.views',
    url(r'^$', 'index', name='index'),
    url(r'^prueba$', 'prueba', name='prueba'),
    url(r'^all_urls_view', 'all_urls_view', name='all_urls_view'),
    url(r'^(?P<year>\d+)/(?P<metric>\w+)$', 'country_metric_view', name='country_metric_view'),
    url(r'^(?P<year>\d+)/(?P<province_code>\d+)/(?P<type>\w+)/(?P<metric>\w+)$', 'one_province_metric_view', name='one_province_metric_view'),
    url(r'^(?P<year>\d+)/(?P<ine_code>\w+)/(?P<metric>\w+)$', 'one_aapp_metric_view', name='one_aapp_metric_view'),
    url(r'^api/autocomplete_publicadministrations/$', 'autocomplete_publicadministrations', name='autocomplete_publicadministrations'),
    url(r'^api/autocomplete_indicators/', 'autocomplete_indicators', name='autocomplete_indicators'),
    url(r'^api/autocomplete_provinces/', 'autocomplete_provinces', name='autocomplete_provinces'),
    url(r'^navigation_form/', 'navigation_form', name='navigation_form'),

)

I think this setting is ok, I can visit any of my pages, and there is no problem until I try to resolve an url in a template tag. The error must be in the project urls.py, when I call to include the app urls.py, because I found out that if in my settings.py i set it like this:

ROOT_URLCONF = 'tdcp.urls'

like this it works!!, it render pages and resolve any url tag in my templates, buuuuut if i set like:

# ROOT_URLCONF = 'urls'

therefore using the include call it stops resolving urls.

I found this shell test of urlresolver, and I tried it to find out the dictionary of ulrs used when urlresolve in reverse(). And of course this it what happens in both scenarios:

with ROOT_URLCONF = 'tdcp.urls'

>>> from django.core import urlresolvers
>>> from tdcp import views
>>> print urlresolvers.get_resolver(None).reverse_dict
<MultiValueDict: {'index': [([(u'', [])], '$', {})], 'autocomplete_publicadministrations': [([(u'api/autocomplete_publicadministrations/', [])], 'api/autocomplete_publicadministrations/$', {})], 'autocomplete_provinces': [([(u'api/autocomplete_provinces/', [])], 'api/autocomplete_provinces/', {})], 'prueba': [([(u'prueba', [])], 'prueba$', {})], <function country_metric_view at 0x02004670>: [([(u'%(year)s/%(metric)s', [u'year', u'metric'])], '(?P<year>\\d+)/(?P<metric>\\w+)$', {})], 'one_province_metric_view': [([(u'%(year)s/%(province_code)s/%(type)s/%(metric)s', [u'year', u'province_code', u'type', u'metric'])], '(?P<year>\\d+)/(?P<province_code>\\d+)/(?P<type>\\w+)/(?P<metric>\\w+)$', {})], <function one_province_metric_view at 0x020046B0>: [([(u'%(year)s/%(province_code)s/%(type)s/%(metric)s', [u'year', u'province_code', u'type', u'metric'])], '(?P<year>\\d+)/(?P<province_code>\\d+)/(?P<type>\\w+)/(?P<metric>\\w+)$', {})], 'one_aapp_metric_view': [([(u'%(year)s/%(ine_code)s/%(metric)s', [u'year', u'ine_code', u'metric'])], '(?P<year>\\d+)/(?P<ine_code>\\w+)/(?P<metric>\\w+)$', {})], <function one_aapp_metric_view at 0x020046F0>: [([(u'%(year)s/%(ine_code)s/%(metric)s', [u'year', u'ine_code', u'metric'])], '(?P<year>\\d+)/(?P<ine_code>\\w+)/(?P<metric>\\w+)$', {})], 'navigation_form': [([(u'navigation_form/', [])], 'navigation_form/', {})], <function index at 0x02004630>: [([(u'', [])], '$', {})], <function all_urls_view at 0x01A917B0>: [([(u'all_urls_view', [])], 'all_urls_view', {})], <function autocomplete_provinces at 0x02004530>: [([(u'api/autocomplete_provinces/', [])], 'api/autocomplete_provinces/', {})], <function prueba at 0x020045F0>: [([(u'prueba', [])], 'prueba$', {})], 'autocomplete_indicators': [([(u'api/autocomplete_indicators/', [])], 'api/autocomplete_indicators/', {})], <function autocomplete_indicators at 0x02004570>: [([(u'api/autocomplete_indicators/', [])], 'api/autocomplete_indicators/', {})], <function navigation_form at 0x020045B0>: [([(u'navigation_form/', [])], 'navigation_form/', {})], 'country_metric_view': [([(u'%(year)s/%(metric)s', [u'year', u'metric'])], '(?P<year>\\d+)/(?P<metric>\\w+)$', {})], 'all_urls_view': [([(u'all_urls_view', [])], 'all_urls_view', {})], <function autocomplete_publicadministrations at 0x01FFC5F0>: [([(u'api/autocomplete_publicadministrations/', [])], 'api/autocomplete_publicadministrations/$', {})]}>
>>> print urlresolvers.get_resolver(None).reverse_dict.items()[0][0]
index

with ROOT_URLCONF = 'urls'

>>> from django.core import urlresolvers
>>> from tdcp import views
>>> print urlresolvers.get_resolver(None).reverse_dict <MultiValueDict: {}>
>>> print urlresolvers.get_resolver(None).reverse_dict.items()[0][0] Traceback (most recent call last):   File "<console>", line 1, in <module> IndexError: list index out of range

What am I doing wrong??

ONE MORE TEST

I updated the project urls.py like this:
from django.conf.urls import patterns, include, url


# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
    # Uncomment the next line to enable the admin:
    url(r'^admin/', include(admin.site.urls)),

    # project urls
    url(r'^hola', 'hola', name='hola'),

    # include app urls
    url(r'^/', include('tdcp.urls', namespace='tdcp')),
    )

So now, when I print in the shell the urlresolve dictionary it just finds the only static url that hangs of the urls.py project, none of the included urls.py, either admin/ or my app tdcp/

>>> from django.core import urlresolvers
>>> from tdcp import views
>>> print urlresolvers.get_resolver(None).reverse_dict
<MultiValueDict: {'hola': [([(u'hola', [])], 'hola', {}), ([(u'hola', [])], 'hola', {})]}>

Upvotes: 2

Views: 1045

Answers (1)

David Irving
David Irving

Reputation: 21

I'm new to Django myself so I'm not 100% sure on this, but I think part of the problem might be in the way you declared the regular expression for the include in your project urls.py.

Instead of

url('', include('tdcp.urls', namespace='tdcp'))

try

url(r'^/', include('tdcp.urls', namespace='tdcp')).

Here is a relevant snippet from the Django documentation:

Note that the regular expressions in this example don’t have a $ (end-of-string match character) but do include a trailing slash. Whenever Django encounters include(), it chops off whatever part of the URL matched up to that point and sends the remaining string to the included URLconf for further processing.

Since you passed in the empty regex, the entire URL matches and so there is nothing left to pass to the included URLConf. I'm not sure how it would play out with the reverse resolver but it might be breaking that, too. (I did a quick skim through the Django code to see if it special cases the empty string but didn't see it -- it's possible I missed it.)

Upvotes: 2

Related Questions