Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django 1.9 to 1.10 raises NoReverseMatch: u'en-gb' is not a registered namespace

I am trying to update my 1.9 application to 1.10 and I am getting the following error on running all my unit tests:

Traceback (most recent call last):   File "/home/…/tests/views/test_configurator.py", line 261, in test_view_configurator_post
    args=[self.configurator.id]),   File "/home/…/.virtualenvs/intranet/lib/python2.7/site-packages/django/urls/base.py", line 87, in reverse
    raise NoReverseMatch("%s is not a registered namespace" % key) NoReverseMatch: 'en-gb' is not a registered namespace

My setting.py file contains the following:

LANGUAGE_CODE = 'en-gb'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
TIME_ZONE = 'Europe/London'

What am I missing?

like image 397
Sardathrion - against SE abuse Avatar asked Oct 07 '16 13:10

Sardathrion - against SE abuse


3 Answers

I encountered this as well, and I narrowed down the cause. I think it's a regression in Django, but I don't have time to write up a full bug report. Here's what I know.

Django waits until the first call to django.urls.reverse to populate all the namespaces to a cached dict.

There's been some changes to that population procedure recently. They added a populating flag that is set to True when you start populating, and is shared across calls to reverse. If the population process happens to make a call to django.urls.reverse, the flag will prevent infinite recursion.

The population process involves importing URL patterns - the urls.py files you have in your apps. If anything during that import process raises an exception, e.g. an undefined name at the top-level of a module in my case, the population algorithm doesn't catch that, and just stops outright, and leaves the populating flag to True. That error, at least for me, was propagated to the top level and I saw it in test runner output.

All subsequent calls to django.urls.reverse raise a NoReverseMatch error for the en-us namespace. Following the code, this is because at the start of the population procedure, if the populating flag is truthy, the process just returns and returns the cached namespace dict, which is empty, causing a KeyError for en-us, causing a NoReverseMatch for en-us.

You should look at the errors that occurred before the first NoReverseMatch to find your culprit. For more info, I think this is the commit that introduced the regression. It has a link to the Django issue it fixed. I think the fix would be to set the populating flag to False in case of an exception, but I'm not sure.

like image 126
Tommi Kaikkonen Avatar answered Sep 19 '22 01:09

Tommi Kaikkonen


Run django system check command it may show the underlying problem:

python manage.py check
like image 34
Janusz Skonieczny Avatar answered Sep 22 '22 01:09

Janusz Skonieczny


I updated to django 1.10.5 and the problem went away.

Go figure!

like image 29
Sardathrion - against SE abuse Avatar answered Sep 23 '22 01:09

Sardathrion - against SE abuse