在Django框架中设置语言偏好的教程
作者:goldensun 发布时间:2022-01-18 22:47:35
一旦你准备好了翻译,如果希望在Django中使用,那么只需要激活这些翻译即可。
在这些功能背后,Django拥有一个灵活的模型来确定在安装和使用应用程序的过程中选择使用的语言。
要设定一个安装阶段的语种偏好,请设定LANGUAGE_CODE。如果其他翻译器没有找到一个译文,Django将使用这个语种作为缺省的翻译最终尝试。
如果你只是想要用本地语言来运行Django,并且该语言的语言文件存在,只需要简单地设置 LANGUAGE_CODE 即可。
如果要让每一个使用者各自指定语言偏好,就需要使用 LocaleMiddleware 。 LocaleMiddleware 使得Django基于请求的数据进行语言选择,从而为每一位用户定制内容。 它为每一个用户定制内容。
使用 LocaleMiddleware 需要在 MIDDLEWARE_CLASSES 设置中增加 'django.middleware.locale.LocaleMiddleware' 。 中间件的顺序是有影响的,最好按照依照以下要求:
保证它是第一批安装的中间件类。
因为 LocalMiddleware 要用到session数据,所以需要放在 SessionMiddleware 之后。
如果你使用CacheMiddleware,把LocaleMiddleware放在它后面。
例如, MIDDLE_CLASSES 可能会是如此:
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
)
LocaleMiddleware 按照如下算法确定用户的语言:
首先,在当前用户的 session 的中查找django_language键;
如未找到,它会找寻一个cookie
还找不到的话,它会在 HTTP 请求头部里查找Accept-Language, 该头部是你的浏览器发送的,并且按优先顺序告诉服务器你的语言偏好。 Django会尝试头部中的每一个语种直到它发现一个可用的翻译。
以上都失败了的话, 就使用全局的 LANGUAGE_CODE 设定值。
备注:
在上述每一处,语种偏好应作为字符串,以标准的语种格式出现。 例如,巴西葡萄牙语是pt-br
如果一个基本语种存在而亚语种没有指定,Django将使用基本语种。 比如,如果用户指定了 de-at (澳式德语)但Django只有针对 de 的翻译,那么 de 会被选用。
只有在 LANGUAGES 设置中列出的语言才能被选用。 若希望将语言限制为所提供语言中的某些(因为应用程序并不提供所有语言的表示),则将 LANGUAGES 设置为所希望提供语言的列表,例如: 例如:
LANGUAGES = (
('de', _('German')),
('en', _('English')),
)
上面这个例子限制了语言偏好只能是德语和英语(包括它们的子语言,如 de-ch 和 en-us )。
如果自定义了 LANGUAGES ,将语言标记为翻译字符串是可以的,但是,请不要使用 django.utils.translation 中的 gettext() (决不要在settings文件中导入 django.utils.translation ,因为这个模块本身是依赖于settings,这样做会导致无限循环),而是使用一个“虚构的” gettext() 。
解决方案就是使用一个“虚假的” gettext() 。以 下是一个settings文件的例子:
ugettext = lambda s: s
LANGUAGES = (
('de', ugettext('German')),
('en', ugettext('English')),
)
这样做的话, make-messages.py 仍会寻找并标记出将要被翻译的这些字符串,但翻译不会在运行时进行,故而需要在任何使用 LANGUAGES 的代码中用“真实的” ugettext()。
LocaleMiddleware 只能选择那些Django已经提供了基础翻译的语言。 如果想要在应用程序中对Django中还没有基础翻译的语言提供翻译,那么必须至少先提供该语言的基本的翻译。 例如,Django使用特定的信息ID来翻译日期和时间格式,故要让系统正常工作,至少要提供这些基本的翻译。
以英语的 .po 文件为基础,翻译其中的技术相关的信息,可能还包括一些使之生效的信息。
技术相关的信息ID很容易被认出来:它们都是大写的。 这些信息ID的翻译与其他信息不同:你需要提供其对应的本地化内容。 例如,对于 DATETIME_FORMAT (或 DATE_FORMAT 、 TIME_FORMAT ),应该提供希望在该语言中使用的格式化字符串。 格式被模板标签now用来识别格式字符串。
一旦LocaleMiddleware决定用户的偏好,它会让这个偏好作为request.LANGUAGE_CODE对每一个HttpRequest有效。请随意在你的视图代码中读一读这个值。 以下是一个简单的例子:
def hello_world(request):
if request.LANGUAGE_CODE == 'de-at':
return HttpResponse("You prefer to read Austrian German.")
else:
return HttpResponse("You prefer to read another language.")
注意,对于静态翻译(无中间件)而言,此语言在settings.LANGUAGE_CODE中,而对于动态翻译(中间件),它在request.LANGUAGE_CODE中。
在你自己的项目中使用翻译
Django使用以下算法寻找翻译:
首先,Django在该视图所在的应用程序文件夹中寻找 locale 目录。 若找到所选语言的翻译,则加载该翻译。
第二步,Django在项目目录中寻找 locale 目录。 若找到翻译,则加载该翻译。
最后,Django使用 django/conf/locale 目录中的基本翻译。
以这种方式,你可以创建包含独立翻译的应用程序,可以覆盖项目中的基本翻译。 或者,你可以创建一个包含几个应用程序的大项目,并将所有需要的翻译放在一个大的项目信息文件中。 决定权在你手中。
所有的信息文件库都是以同样方式组织的: 它们是:
$APPPATH/locale/<language>/LC_MESSAGES/django.(po|mo)
$PROJECTPATH/locale/<language>/LC_MESSAGES/django.(po|mo)
所有在settings文件中 LOCALE_PATHS 中列出的路径以其列出的顺序搜索 <language>/LC_MESSAGES/django.(po|mo)
$PYTHONPATH/django/conf/locale/<language>/LC_MESSAGES/django.(po|mo)
要创建信息文件,也是使用 django-admin.py makemessages.py 工具,和Django信息文件一样。 需要做的就是进入正确的目录—— conf/locale (在源码树的情况下)或者 locale/ (在应用程序信息或项目信息的情况下)所在的目录下。 同样地,使用 compile-messages.py 生成 gettext 需要使用的二进制 django.mo 文件。
您亦可运行django-admin.py compilemessages --settings=path.to.settings 来使编译器处理所有存在于您 LOCALE_PATHS 设置中的目录。
应用程序信息文件稍微难以发现——因为它们需要 LocaleMiddle 。如果不使用中间件,Django只会处理Django的信息文件和项目的信息文件。
最后,需要考虑一下翻译文件的结构。 若应用程序要发放给其他用户,应用到其它项目中,可能需要使用应用程序相关的翻译。 但是,使用应用程序相关的翻译和项目翻译在使用 make-messages 时会产生古怪的问题。它会遍历当前路径下所有的文件夹,这样可能会把应用消息文件里存在的消息ID重复放入项目消息文件中。
最容易的解决方法就是将不属于项目的应用程序(因此附带着本身的翻译)存储在项目树之外。 这样做的话,项目级的 make-messages 将只会翻译与项目精确相关的,而不包括那些独立发布的应用程序中的字符串。


猜你喜欢
- 项目场景:postman通常需要传递各式各样的参数,这样的话,进行写参数比较头疼,不知怎么进行传参。解决方案:可以考虑将参数对象写成json
- HTTP-REFERER这个变量已经越来越不可靠了,完全就是可以伪造出来的东东。 以下是伪造方法:ASP/Visual Basic代码 di
- 项目用run dev build 打包后,发现很多图片都不显示,在本地是没有问题的啊!找原因发现通过webpack+vuecli默认打包的c
- 本文给大家介绍vue2.0+webpack环境构造过程。1.首先新建一个目录vue-wkdemo,这是我们的项目目录。执行 npm init
- 序列解包(Sequence Unpacking)是Python中非常重要和常用的一个功能,可以使用非常简洁的形式完成复杂的功能,大幅度提高了
- 前言在任何编程语言中,代码需要根据不同的条件在给定的输入中做不同的决定和执行相应的动作。例如,在一个游戏中,如果玩家生命点为0,游戏结束。在
- 在用户研究工作中,如何让自己的数据和结论更有说服力,是很重要的问题。最近将自己积累的用研信度和效度的笔记整理一下,罗列在文中,希望对大家有所
- 这是最近碰到一个问题,先描述下问题:首先我有一个训练好的模型(例如vgg16),我要对这个模型进行一些改变,例如添加一层全连接层,用于种种原
- 一、YOLOv5简介YOLOv5是一种目标检测算法,由ultralytics公司开发。它采用单一神经网络同时完成对象识别和边界框回归,并使用
- <td width="15%" align="left">是否为分包人&l
- Python函数的定义定义函数,也就是创建一个函数,可以理解为创建一个具有某些用途的工具。定义函数需要用 def 关键字实现,具体的语法格式
- 1.生成日志并通过http传输出去(通过HTTPHandler方式):#生成并发送日志import loggingfrom logging.
- 多进程&多线程服务端:多进程和多线程的开启方式相同。缺点:<1> 由于Cpython的GIL,导致同一时间无法运行多个线
- asp之家注:防止表单重复提交的方法,在客户端其实很容易实现,只要使用js让用户第一次点击提交按钮后,把提交按钮设置为disabled,这样
- 代码很简洁,这里就不多废话了,直接上源码html代码 <!doctype html> <html>
- 前言在本次python文章中,主要通过定义一个排序方法,实现一组数列能够按照另一组数列指定的位置进行重新排序输出,默认正序排序,可通过Tru
- 本文实例讲述了Python使用循环神经网络解决文本分类问题的方法。分享给大家供大家参考,具体如下:1、概念1.1、循环神经网络循环神经网络(
- 实际应用中,会遇到需要把表的某些行转换成列,或者把列转换成行的情况。比如一张表在数据库中是这样的:图1但是,需要的结果可能是这样:图2这个时
- 本文实例讲述了python使用socket进行简单网络连接的方法。分享给大家供大家参考。具体如下:import socketprint &q
- 技术背景GPU的加速技术在深度学习、量子计算领域都已经被广泛的应用。其适用的计算模型是小内存的密集型计算场景,如果计算的模型内存较大,则需要