4

I have a Django project, training and an app inside this project, tests. The folder structure looks like this:

django-training
    tests
        urls.py
    training
        urls.py

Inside training/urls.py I have this pattern defined:

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

And inside tests/urls.py I have these patterns defined:

url(r'^$', index, name='index'),
url(r'^(\d+)/$', view, name='view'),
url(r'^give-up/$', give_up, name='give_up'),
url(r'^(\d+)/result/$', result, name='result')

Everything works fine.

But, what if I want to package the tests app as a reusable app that works in any Django project? What should I do with the URL patterns?

I created a tests/settings.py file and changed the ROOT_URLCONF config var to point to tests/urls.py. But this won't work, as this error will arise:

Traceback (most recent call last):
File "/home/user/.virtualenvs/clean2/local/lib/python2.7/site-packages/tests/tests.py", line 173, in testContext
    response = self.client.get(reverse('tests:view', args=(1,)))
File "/home/user/.virtualenvs/clean2/local/lib/python2.7/site-packages/django/core/urlresolvers.py", line 492, in reverse
key)
NoReverseMatch: u'tests' is not a registered namespace

The error is quite logic, since reverse needs the namespace to be defined (tests, that is).

My question is: how and where shall I define this namespace for the reusable app so that URLs will work independent of the Django project the app is installed in?

linkyndy
  • 17,038
  • 20
  • 114
  • 194

2 Answers2

3

I've found a quick solution to this problem in the Django manual.

In my tests/urls.py I've included the test namespace as so:

test_patterns = patterns('',
    url(r'^$', index, name='index'),
    url(r'^(\d+)/$', view, name='view'),
    url(r'^give-up/$', give_up, name='give_up'),
    url(r'^(\d+)/result/$', result, name='result'),
)

urlpatterns = patterns('',
    url(r'^tests/', include(test_patterns, namespace='tests')),
)

URL reverse problems are now solved and everything works as expected.

linkyndy
  • 17,038
  • 20
  • 114
  • 194
2

The problem arises because you are doing some testing, and this have not added tests's url to the main urls.py, this is why:

response = self.client.get(reverse('tests:view', args=(1,)))

Gives:

u'tests' is not a registered namespace

Because you have not added the tests package in your main urls.py file.

Games Brainiac
  • 80,178
  • 33
  • 141
  • 199
  • 1
    I know what the problem is, I didn't know how to solve it. Which was the main `urls.py` file if I was testing only my reusable app? – linkyndy Oct 30 '13 at 09:58
  • @AndreiHorak Just add your testing app to your main `urls.py`, and register it as an app, it should work fine then. – Games Brainiac Oct 30 '13 at 09:59
  • I am testing a sole reusable app, I don't understand which `urls.py` are you talking about. I installed my app package with `pip` and ran `django-admin.py test tests --settings=tests.settings`. I have no other `urls.py` than the one in `tests/urls.py`. – linkyndy Oct 30 '13 at 10:02
  • So, `tests` is your only app? – Games Brainiac Oct 30 '13 at 10:02
  • Yes, `tests` is the only app. – linkyndy Oct 30 '13 at 10:03