Skip to content

Instantly share code, notes, and snippets.

@vstoykov
Last active October 16, 2024 13:56
Show Gist options
  • Save vstoykov/1366794 to your computer and use it in GitHub Desktop.
Save vstoykov/1366794 to your computer and use it in GitHub Desktop.
Force Django to use settings.LANGUAGE_CODE for default language instead of request.META['HTTP_ACCEPT_LANGUAGE']
try:
from django.utils.deprecation import MiddlewareMixin
except ImportError:
MiddlewareMixin = object
class ForceDefaultLanguageMiddleware(MiddlewareMixin):
"""
Ignore Accept-Language HTTP headers
This will force the I18N machinery to always choose settings.LANGUAGE_CODE
as the default initial language, unless another one is set via sessions or cookies
Should be installed *before* any middleware that checks request.META['HTTP_ACCEPT_LANGUAGE'],
namely django.middleware.locale.LocaleMiddleware
"""
def process_request(self, request):
if 'HTTP_ACCEPT_LANGUAGE' in request.META:
del request.META['HTTP_ACCEPT_LANGUAGE']
@enginipek
Copy link

thanks for this! wandering around for an answer for almost a week! this saved the day!

@mahdin75
Copy link

mahdin75 commented Oct 10, 2019

Thanks. I added this middleware before any other middleware that is using language code and it works now.

@sergeyklay
Copy link

sergeyklay commented Mar 1, 2021

Yet another version:

from contextlib import suppress

from django.conf import settings


def inject_accept_language(get_response):
    """
    Ignore Accept-Language HTTP headers.

    This will force the I18N machinery to always choose

      - Ukrainian for the main site
      - ADMIN_LANGUAGE_CODE for the admin site

    as the default initial language unless another one is set via
    sessions or cookies.

    Should be installed *before* any middleware that checks
    request.META['HTTP_ACCEPT_LANGUAGE'], namely
    `django.middleware.locale.LocaleMiddleware`.
    """
    admin_lang = getattr(settings, 'ADMIN_LANGUAGE_CODE',
                         settings.LANGUAGE_CODE)

    def middleware(request):
        # Force Ukrainian locale for the main site
        lang = admin_lang if request.path.startswith('/admin') else 'uk'
        accept = request.META.get('HTTP_ACCEPT_LANGUAGE', []).split(',')

        with suppress(ValueError):
            # Remove `lang` from the HTTP_ACCEPT_LANGUAGE to avoid duplicates
            accept.remove(lang)

        accept = [lang] + accept
        request.META['HTTP_ACCEPT_LANGUAGE'] = f"""{','.join(accept)}"""
        return get_response(request)

    return middleware

@dismine
Copy link

dismine commented Oct 18, 2021

Yet another version:

from contextlib import suppress

from django.conf import settings


def inject_accept_language(get_response):
    """
    Ignore Accept-Language HTTP headers.

    This will force the I18N machinery to always choose

      - Ukrainian for the main site
      - ADMIN_LANGUAGE_CODE for the admin site

    as the default initial language unless another one is set via
    sessions or cookies.

    Should be installed *before* any middleware that checks
    request.META['HTTP_ACCEPT_LANGUAGE'], namely
    `django.middleware.locale.LocaleMiddleware`.
    """
    admin_lang = getattr(settings, 'ADMIN_LANGUAGE_CODE',
                         settings.LANGUAGE_CODE)

    def middleware(request):
        # Force Ukrainian locale for the main site
        lang = admin_lang if request.path.startswith('/admin') else 'uk'
        accept = request.META.get('HTTP_ACCEPT_LANGUAGE', []).split(',')

        with suppress(ValueError):
            # Remove `lang` from the HTTP_ACCEPT_LANGUAGE to avoid duplicates
            accept.remove(lang)

        accept = [lang] + accept
        request.META['HTTP_ACCEPT_LANGUAGE'] = f"""{','.join(accept)}"""
        return get_response(request)

    return middleware

Thank you for this version. But it has issue

accept = request.META.get('HTTP_ACCEPT_LANGUAGE', []).split(',')

It will crash with error 'list' object has no attribute 'split'. I think it should be instead

accept = request.META.get('HTTP_ACCEPT_LANGUAGE', "").split(',')

@sergeyklay
Copy link

@dismine Yes, you're right! 👍

@Inayatullahsh
Copy link

Thank You so much @vstoykov!

@ionsurdu
Copy link

thanks, saved my day

@andre-fuchs
Copy link

Thanks everybody involved!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment