Repository: django-cms/django-cms

Issue:
Server error 500 if no accept_language header is present
If a bot like the google bots who does not set the accept_language header is visiting the page without a language prefix and i18n is activated, following error is thrown:

NoReverseMatch: Reverse for 'pages-details-by-slug' with arguments '()' and keyword arguments '{'slug': ''}' not found.

Only happens if DEBUG is False.



Discussion:
I just spent the last 7 hours encountering this same issue. It's especially a problem when a third-party service (i.e. Instagram) tries to call a callback url without the header set.

I actually just figured this out, although I don't completely understand the problem.

In my case, I had set the available Django LANGUAGES setting to use only one -  'en'. However, the default LANGUAGE_CODE setting is 'en-us'. Accordingly, when requests were made without the language header were made, Django assumed it wanted a response in 'en-us'. In my case, no page actually existed in that language, because my pages only existed in 'en'.

The CMS will offer the option to localize the content for every language specified in LANGUAGES. By default, that's every language that Django supports, and results in an admin with a billion language choices. I didn't want that, which is why I set the LANGUAGES to a single choice, and ended up using the wrong language code.

same issue here, solved it by setting LANGUAGES and LANGUAGE_CODE to matching values.

Same issue, my languages variables are:

```
LANGUAGE_CODE = 'es-ar'
LANGUAGES = (
    ('es', gettext('Spanish')),
    ('en', gettext('English')),
)
```

Like @ryanbagwell says, looks like Django are searching a erroneous language, if the page have both language versions, no problem. Also only occurs when the user is sign-in.

Tested with the latest 3.0.0.beta3 and Python 2.7.


Resolving patch:
diff --git a/cms/utils/conf.py b/cms/utils/conf.py
--- a/cms/utils/conf.py
+++ b/cms/utils/conf.py
@@ -194,6 +194,10 @@ def get_languages():
     if not settings.USE_I18N:
         return _ensure_languages_settings(
             {settings.SITE_ID: [{'code': settings.LANGUAGE_CODE, 'name': settings.LANGUAGE_CODE}]})
+    if not settings.LANGUAGE_CODE in dict(settings.LANGUAGES):
+        raise ImproperlyConfigured(
+                        'LANGUAGE_CODE "%s" must have a matching entry in LANGUAGES' % settings.LANGUAGE_CODE
+                    )
     languages = getattr(settings, 'CMS_LANGUAGES', {
         settings.SITE_ID: [{'code': code, 'name': _(name)} for code, name in settings.LANGUAGES]
     })


Test patch:
diff --git a/cms/tests/i18n.py b/cms/tests/i18n.py
--- a/cms/tests/i18n.py
+++ b/cms/tests/i18n.py
@@ -5,7 +5,7 @@
 class TestLanguages(SettingsOverrideTestCase):
 
     settings_overrides = {
-        'LANGUAGE_CODE': 'en-us',
+        'LANGUAGE_CODE': 'en',
         'LANGUAGES': (('fr', 'French'),
                       ('en', 'English'),
                       ('de', 'German'),
@@ -73,7 +73,7 @@ def test_get_languages_undefined_site(self):
 class TestLanguagesNoDefault(SettingsOverrideTestCase):
 
     settings_overrides = {
-        'LANGUAGE_CODE': 'en-us',
+        'LANGUAGE_CODE': 'en',
         'LANGUAGES': (('fr', 'French'),
                       ('en', 'English'),
                       ('de', 'German'),
diff --git a/cms/tests/multilingual.py b/cms/tests/multilingual.py
--- a/cms/tests/multilingual.py
+++ b/cms/tests/multilingual.py
@@ -267,3 +267,4 @@ def test_no_english_defined(self):
                 update_site_and_page_choices(lang='en-us')
             except LanguageError:
                 self.fail("LanguageError raised")
+
diff --git a/cms/tests/settings.py b/cms/tests/settings.py
--- a/cms/tests/settings.py
+++ b/cms/tests/settings.py
@@ -20,3 +20,10 @@ def test_non_numeric_site_id(self):
                 ImproperlyConfigured,
                 get_cms_setting, 'LANGUAGES'
             )
+
+    def test_invalid_language_code(self):
+        with SettingsOverride(LANGUAGE_CODE='en-us'):
+            self.assertRaises(
+                ImproperlyConfigured,
+                get_cms_setting, 'LANGUAGES'
+            )