amazon ec2 - Flask Babel inconsistent language switching in production - Stack Overflow

时间: 2025-01-06 admin 业界

I am developing a Flask application that uses Flask-Babel for language translation. The app works perfectly on my local environment, but in production on an AWS EC2 Ubuntu instance behind a load balancer, the language switching behaves inconsistently.

When navigating to a URL like /, the page displays text in the wrong language (e.g., German or English instead of French).

Refreshing the page does sometimes change the language without changing the selector, and switching the language with the selector does not change the language sometimes.

init.py

def create_app():
    app = Flask(__name__)
    app.config.from_object(os.environ.get("FLASK_CONFIG"))
    app.app_context().push()
    Session(app)

    def get_locale():
        if not g.get('lang_code', None):
            g.lang_code = request.accept_languages.best_match(
                app.config["LANGUAGES"], default="de")
        return g.lang_code

    babel = Babel(app)
    babel.init_app(app, locale_selector=get_locale)

    from app.webpage import webpage as webpage_blueprint

    with app.app_context():
        app.register_blueprint(webpage_blueprint)

    @app.route("/")
    def home():
        if not g.get('lang_code', None):
            get_locale()
        return redirect(url_for("webpage.main.index"))

    return app

routes.py

from flask import current_app, render_template, g, request, session,
from flask_babel import _, refresh
from app.webpage.main import main

@main.url_defaults
def add_language_code(endpoint, values):
    if "lang_code" not in values:
        values.setdefault("lang_code", g.lang_code)


@main.url_value_preprocessor
def pull_lang_code(endpoint, values):
    g.lang_code = values.pop("lang_code", current_app.config["BABEL_DEFAULT_LOCALE"])


@main.before_request
def before_request():
    if g.lang_code not in current_app.config["LANGUAGES"]:
        g.lang_code = current_app.config["BABEL_DEFAULT_LOCALE"]

    if request.url_rule:
        dfl = request.url_rule.defaults or {}
        if "lang_code" in dfl and dfl["lang_code"] != g.lang_code:
            g.lang_code = current_app.config["BABEL_DEFAULT_LOCALE"]

@main.route("/")
def index():
    return render_template("main/index.html")

@main.route("/about")
def about():
    return render_template("main/about.html")

@main.route("/contact")
def contact():
    return render_template("main/contact.html")

base.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{% block title %}caredata{% endblock %}</title>
    <link rel="shortcut icon" href="{{ url_for('static', filename='img/favicon.ico') }}">
    <link href="{{url_for('static',filename='css/styles.css')}}" rel="stylesheet">
    <script src="{{url_for('static', filename='js/appendix.js')}}"></script>

</head>
<body>
  {% block language %}
  <div class="w-full px-4 sm:px-6">
    <div id="language-picker-container" class="max-w-7xl mx-auto flex justify-end p-2">
      <form action="" method="get" id="language-picker-form" class="relative">
        <select id="language-picker-select" name="lang_code" onchange="location = this.value;" class="cursor-pointer appearance-none py-1 pl-3 pr-8 text-sm text-gray-900">
          <option value="{{ url_for(request.endpoint, lang_code='de', **request.view_args) }}" 
                {{ 'selected' if g.lang_code == 'de' else '' }}>
                DE
          </option>
          <option value="{{ url_for(request.endpoint, lang_code='en', **request.view_args) }}" 
                {{ 'selected' if g.lang_code == 'en' else '' }}>
                EN
          </option>
          <option value="{{ url_for(request.endpoint, lang_code='fr', **request.view_args) }}" 
                {{ 'selected' if g.lang_code == 'fr' else '' }}>
                FR
          </option>
        </select>
         <svg class="absolute right-2 top-1/2 transform -translate-y-1/2 pointer-events-none size-4 text-gray-500"" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" data-slot="icon">
          <path fill-rule="evenodd" d="M4.22 6.22a.75.75 0 0 1 1.06 0L8 8.94l2.72-2.72a.75.75 0 1 1 1.06 1.06l-3.25 3.25a.75.75 0 0 1-1.06 0L4.22 7.28a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd" />
        </svg>
      </form>
    </div>
  </div>
    {% endblock %}
最新文章