Django本地化配置完成但语言切换失效,请求返回302状态码
Hey there, let's troubleshoot why your Django language switch is returning a 302 but not actually updating the displayed language. I've hit this exact issue a handful of times, so here are the most common fixes to walk through:
Middleware order in Django make-or-breaks localization functionality. LocaleMiddleware must be placed:
- After
SessionMiddlewareandCookieMiddleware(it needs access to session/cookie storage to save user language preferences) - Before
CommonMiddleware(it needs to process language settings before the request path is handled)
Here's a valid middleware order example:
MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.locale.LocaleMiddleware', # Critical position here 'django.middleware.common.CommonMiddleware', # Rest of your middleware... ]
If this order is wrong, Django can't properly read or write the user's language preference to the session/cookie.
Make sure your form strictly follows Django's requirements for the set_language view:
- Uses a POST request with action pointing to
{% url 'set_language' %} - Includes a field named
languagewith values matching yourLANGUAGEScodes (ru/en) - Includes a CSRF token (required for POST requests in Django)
- Optional but recommended: A
nexthidden field to redirect back to the current page
Example of a correctly structured form:
<form action="{% url 'set_language' %}" method="post"> {% csrf_token %} <input name="next" type="hidden" value="{{ request.path }}"> <select name="language"> {% get_current_language as LANGUAGE_CODE %} {% get_available_languages as LANGUAGES %} {% get_language_info_list for LANGUAGES as languages %} {% for language in languages %} <option value="{{ language.code }}" {% if language.code == LANGUAGE_CODE %}selected{% endif %}> {{ language.name_local }} ({{ language.code }}) </option> {% endfor %} </select> <button type="submit">Switch Language</button> </form>
Double-check that the language field's values exactly match the codes in your LANGUAGES setting (no typos like RU instead of ru).
After submitting the form, check your browser's developer tools (Application tab in Chrome, Storage tab in Firefox):
- Look for a
django_languagecookie with the value you selected (e.g.,ru) - If using session-based storage, check the session data for a
_languagekey with the correct code
If these values aren't updating, Django isn't saving your language preference—this usually ties back to middleware order or session configuration issues.
Your current LOCALE_PATHS has a subtle but critical issue: if you're defining a single path in a tuple, you need to add a trailing comma, otherwise it's treated as a string instead of a tuple:
# Wrong (string instead of tuple) LOCALE_PATHS = (project_dir + "/apps/locale") # Correct (proper tuple) LOCALE_PATHS = ( project_dir + "/apps/locale", # Trailing comma is mandatory here )
Without the comma, Django might not find your compiled translation files (django.mo), making it seem like the language didn't switch even if the preference was saved. Also re-run django-admin compilemessages to ensure your translations are up-to-date.
- Ensure
USE_I18N = Trueis set in your settings.py (this is the master switch for all Django localization features) - If you're testing locally, make sure
LANGUAGE_COOKIE_SECURE = False(secure cookies won't work over HTTP) - By default, Django prioritizes browser language preferences over user-selected ones. To override this, you can set
LOCALE_MIDDLEWARE_SESSION_ONLY = Trueto force using the session-stored language.
Sometimes cached content can make it look like the language didn't switch:
- Force-refresh the page (Ctrl+F5) to bypass browser cache
- Clear your browser's cookies and cache entirely
- Temporarily disable any Django caching middleware/backend to test if that's the culprit
内容的提问来源于stack exchange,提问作者Къяр

