如何在 Django 中翻译 Javascript 标准错误消息?

How do I translate Javascript standard error messages in Django?

我有几个使用翻译的 Django 项目,一切正常,除了 Javascript 表单上的错误消息没有翻译。

例如,在我的登录表单上,如果我简单地按下回车键,无论我选择的是英语、法语、德语还是任何其他语言,我都会收到英语的 JS 错误消息 "Please fill in this field"。这不是我的 JS 错误消息,如果我 运行 manage.py makemessages -d djangojs,则此消息不会出现以进行翻译,因此我认为我不需要通过该过程进行更正。

任何人都可以告诉我如何确保用户以他们的语言收到 JavaScript 错误消息。 谢谢

docs 说你应该使用 django-admin makemessages -d djangojs -l de,而不是 python manage.py ...,之后还要确保你 运行 django-admin compilemessages

如果还是不行,您可以尝试使用 trans 标签,然后在您的模板上使用事件侦听器手动添加错误消息。

页面顶部:

{% load trans %}

纯javascript:

var inputs = document.querySelectorAll("input");

inputs.forEach(function(input) {
  if (input.hasAttribute("required")) {
    input.oninvalid = function() {
      this.setCustomValidity("{% trans 'Please fill in this field' %}");
    }
  });
});

jQuery:

$("input[required]").on("invalid", function() {
    this.setCustomValidity("{% trans 'Please fill in this field' %}");
});

如果此解决方案不适用于您的特定用例,docs 将详细介绍各种替代方案。

Django 提供了一个具体的解决方案来处理这个问题:

https://docs.djangoproject.com/en/2.2/topics/i18n/translation/#module-django.views.i18n

但是当需要翻译的js代码中使用的消息数量有限时, 通常情况下,我更喜欢使用更简单的解决方案。

首先,我在"templates"文件夹中创建了一个"js message catalog"; 它只包含一个全局字符串文字列表。

由于模板引擎不限于 HTML,并且可以处理任何文件类型, 可以在js文件开头{% load i18n %},根据需要使用'trans'等模板标签标记可翻译的字符串值; "makemessages" 将按预期检测到这些值。

文件"/myapp/templates/message_catalog.js"

{% load i18n %}

MESSAGE_HELLO = "{% trans 'hello' %}";
MESSAGE_GOODBYE = "{% trans 'goodbye' %}";
...

然后,记得将它包含在主模板中,这样消息目录就会 可从 js 代码访问:

文件"/myapp/templates/base.html"

...
    <script>
        {% include 'message_catalog.js' %}
    </script>

</body>
</html>

'real' js 代码可以像往常一样以静态方式存在,并且仍然可以访问翻译后的消息:

文件"/myapp/static/frontend.js"

function hello() {
    alert(MESSAGE_HELLO);
}

function goodbye() {
    alert(MESSAGE_GOODBYE);
}

在这里,我假设我们讨论的是浏览器提供的表单字段验证。

您可以为整个 HTML 页面指定默认语言, 和一个部分的特定语言,原则上浏览器应该好好利用它。

然而,到目前为止,浏览器对该领域的支持仍然很差且不可靠。

我在 Chrome 和 Safari 上试过了:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>title</title>
    </head>
    <body>

        <p>form with default lang (en)</p>
        <form>
            <input type="text" required>
            <br />
            <input type="submit">Save
        </form>

        <p>form with specific lang (it)</p>
        <form lang="it">
            <input type="text" required>
            <br />
            <input type="submit">Salva
        </form>

    </body>
</html>

这是令人失望的结果:

有一些约束验证DOM方法,比如checkValidity(), setCustomValidity() 和 reportValidity() 可以帮助控制 验证消息,但它们也都被提及得不到很好的支持。

就个人而言,我更喜欢完全禁用浏览器验证,运行 我的 而是拥有服务器端或客户端,以便更好地控制用户交互。

<form ... novalidate>
    ...