Repository: wagtail/wagtail
File: wagtail/admin/localization.py (Python)

Code before:

def get_available_admin_languages():
    return getattr(
        settings, "WAGTAILADMIN_PERMITTED_LANGUAGES", WAGTAILADMIN_PROVIDED_LANGUAGES
    )


@functools.cache
def get_available_admin_time_zones():
    if not settings.USE_TZ:
        return []

    return getattr(
        settings, "WAGTAIL_USER_TIME_ZONES", sorted(zoneinfo.available_timezones())
    )


def get_localized_response(view_func, request, *args, **kwargs):
    user = request.user
    preferred_language = None
    if hasattr(user, "wagtail_userprofile"):
        preferred_language = user.wagtail_userprofile.get_preferred_language()
        time_zone = user.wagtail_userprofile.get_current_time_zone()
    else:
        time_zone = settings.TIME_ZONE
    with override_tz(time_zone), LogContext(user=user):
        if preferred_language:
            with override(preferred_language):
                response = view_func(request, *args, **kwargs)
        else:
            response = view_func(request, *args, **kwargs)

        if hasattr(response, "render"):
            # If the response has a render() method, Django treats it
            # like a TemplateResponse, so we should do the same
            # In this case, we need to guarantee that when the TemplateResponse
            # is rendered, it is done within the override context manager
            # or the user preferred_language/timezone will not be used
            # (this could be replaced with simply rendering the TemplateResponse
            # for simplicity but this does remove some of its middleware modification
            # potential)
            render = response.render

            def overridden_render(response):
                with override_tz(time_zone):
                    if preferred_language:
                        with override(preferred_language):
                            return render()
                    return render()

            response.render = types.MethodType(overridden_render, response)

Review comment (suggestion):
I wonder if `LogContext` should be applied here or kept in `require_admin_access`. The latter would be more appropriate (as it's not related to localization), but the changes wouldn't be a 1:1 cut-paste from the original code.

Code after:
    return getattr(
        settings, "WAGTAILADMIN_PERMITTED_LANGUAGES", WAGTAILADMIN_PROVIDED_LANGUAGES
    )


@functools.cache
def get_available_admin_time_zones():
    if not settings.USE_TZ:
        return []

    return getattr(
        settings, "WAGTAIL_USER_TIME_ZONES", sorted(zoneinfo.available_timezones())
    )


def get_localized_response(view_func, request, *args, **kwargs):
    user = request.user
    preferred_language = None
    if hasattr(user, "wagtail_userprofile"):
        preferred_language = user.wagtail_userprofile.get_preferred_language()
        time_zone = user.wagtail_userprofile.get_current_time_zone()
    else:
        time_zone = settings.TIME_ZONE
    with override_tz(time_zone):
        if preferred_language:
            with override(preferred_language):
                response = view_func(request, *args, **kwargs)
        else:
            response = view_func(request, *args, **kwargs)

        if hasattr(response, "render"):
            # If the response has a render() method, Django treats it
            # like a TemplateResponse, so we should do the same
            # In this case, we need to guarantee that when the TemplateResponse
            # is rendered, it is done within the override context manager
            # or the user preferred_language/timezone will not be used
            # (this could be replaced with simply rendering the TemplateResponse
            # for simplicity but this does remove some of its middleware modification
            # potential)
            render = response.render

            def overridden_render(response):
                with override_tz(time_zone):
                    if preferred_language:
                        with override(preferred_language):
                            return render()
                    return render()

            response.render = types.MethodType(overridden_render, response)
            # decorate the response render method with the override context manager
        return response