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']
@thoreg
Copy link

thoreg commented Jan 13, 2015

thxAlot - you great sorcerer ;)

@harabchuk
Copy link

Thanks!!!

@Lh4cKg
Copy link

Lh4cKg commented Oct 4, 2015

Thanks ;)

@dinopetrone
Copy link

boom...just saved me a couple hours :)

@macolo
Copy link

macolo commented Nov 26, 2016

nice one! For Django 1.10 (and Python 3) its now:


def force_default_language_middleware(get_response):
    """
        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
        """
    # One-time configuration and initialization.

    def middleware(request):
        # Code to be executed for each request before
        # the view (and later middleware) are called.
        if 'HTTP_ACCEPT_LANGUAGE' in request.META:
            del request.META['HTTP_ACCEPT_LANGUAGE']

        response = get_response(request)

        # Code to be executed for each request/response after
        # the view is called.

        return response

    return middleware

@sutyrin
Copy link

sutyrin commented Jan 22, 2017

Whoa... Thanks a lot guys! Beyond 2017))

@yomguy
Copy link

yomguy commented Apr 21, 2017

Great, thanks!

@KalterDK
Copy link

Thanks, man!! ^^

@mrabedini
Copy link

Great! Thanks a lot!
I found this page on stack overflow. I was wondering why it is not the answer on top.

@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