跳转至
受监督的机器翻译

本文内容由机器翻译生成,并遵循人工维护的术语表与风格指南。由于译文未经逐行人工审校,可能偶有错误或表达不当之处。

如有任何出入,请以英文原版为准,英文原版是权威来源。

阅读英文原版

国际化与时区

借助 starlette-admin,你可以按用户本地化 UI 字符串,并将显示的日期时间转换为查看者所在的时区,而不受数据库存储方式的约束。

完整示例: 如需查看演示国际化与时区功能的完整可运行应用,请参阅 GitHub 仓库中的 examples/10-i18n-timezone

安装 i18n extra

翻译支持需要 Babel。缺少它时管理后台仍然可用,但会回退到英文,并跳过区域设置感知的日期与数字格式化。

pip install "starlette-admin[i18n]"
uv add "starlette-admin[i18n]"

设置区域设置

from sqlalchemy import create_engine
from starlette_admin import I18nConfig
from starlette_admin.contrib.sqla import Admin
from starlette_admin.i18n import SUPPORTED_LOCALES

engine = create_engine("sqlite:///admin.sqlite")

admin = Admin(
    engine,
    title="My Admin",
    i18n_config=I18nConfig(
        default_locale="en",
        language_switcher=SUPPORTED_LOCALES,
    ),
    secret_key="a-long-random-string",
)

i18n_config 默认为 None,此时管理界面以英文运行。传入 I18nConfig 后,管理后台会安装 LocaleMiddleware。该中间件会在每个请求上解析出一个区域设置,并将其暴露给模板以及你字段和视图代码中使用的翻译函数(gettextlazy_gettext)。

language_switcher 参数会在管理导航栏中添加一个下拉菜单,供用户选择自己的区域设置。将其保持为默认值 None 即可隐藏切换器,仅依靠 default_locale 和逐请求检测。

I18nConfig 参考

属性 类型 默认值 描述
default_locale str "en" 当没有任何 cookie 或请求头匹配受支持的区域设置时使用的区域设置。
language_cookie_name str | None "language" 用于检测用户区域设置的 cookie。设为 None 可禁用。
language_header_name str | None "Accept-Language" cookie 缺失时读取的请求头。设为 None 可禁用。
language_switcher list[str] | None None 导航栏切换器中提供的区域设置。None 表示隐藏切换器。

区域设置的检测方式

LocaleMiddleware 按照以下顺序在每个请求中解析一次区域设置:

  1. Cookie:language_cookie_name 的值,前提是它匹配某个内置支持的区域设置。
  2. 请求头:Accept-Language 请求头,或你在 language_header_name 中指定的请求头,同样需要通过有效性检查。
  3. 默认值:当 cookie 和请求头都不匹配时,使用 default_locale

内置支持的区域设置(starlette_admin.i18n.SUPPORTED_LOCALES)包括德语、英语、法语、葡萄牙语、俄语、土耳其语以及简体中文和繁体中文。当用户在导航栏中选择语言时,切换器会写入语言 cookie,因此该选择会跨请求持久保留,而无需服务器端会话存储。

时区

from sqlalchemy import create_engine
from starlette_admin import TimezoneConfig
from starlette_admin.contrib.sqla import Admin

engine = create_engine("sqlite:///admin.sqlite")

admin = Admin(
    engine,
    title="My Admin",
    timezone_config=TimezoneConfig(
        default_timezone="UTC",
        database_timezone="UTC",
        timezone_switcher=["UTC", "Europe/Paris", "America/New_York", "Asia/Tokyo"],
    ),
    secret_key="a-long-random-string",
)

Note

i18n_config 不同,timezone_config 默认不为 None。如果省略它,Admin 类会为你构造一个 TimezoneConfig(),因此时区转换开箱即用。管理后台会将不含时区的日期时间视为 database_timezone 中的值(默认为 "UTC"),并向每位用户显示为 "UTC"(即默认的 default_timezone),除非该用户选择了其他时区。

时区的检测方式

TimezoneMiddleware 在每个请求中解析一次时区:

  1. Cookie:timezone_cookie_name 的值(默认为 "timezone"),如果存在的话。
  2. 默认值:否则使用 default_timezone

导航栏的时区切换器会写入这个 cookie,与语言切换器完全一样。时区没有类似 Accept-Language 的请求头可用,因为浏览器不会发送此类信息,所以检测完全依赖 cookie。读取 Intl.DateTimeFormat().resolvedOptions().timeZone 的客户端 JavaScript 通常会设置该 cookie,切换器本身也是如此。

字段值的转换方式

DateTimeFieldArrowField 会在 database_timezone 与查看者解析出的时区之间转换值。

  • 读取(列表、详情、导出):管理后台将数据库中不含时区的值视为 database_timezone 中的值,并在格式化之前将其转换为查看者的时区。
  • 写入(新建和编辑表单):管理后台将提交的值视为查看者时区中的值,并在其到达模型之前将其转换为 database_timezone

这样一来,身处不同时区的两名管理员可以编辑同一行数据,各自看到自己本地的时间,而数据库则始终保持单一、一致的时区。

TimezoneConfig 参考

属性 类型 默认值 描述
default_timezone str "UTC" 未设置 cookie 时使用的时区。接受任意 IANA 时区名称。
timezone_cookie_name str | None "timezone" 用于检测查看者时区的 cookie。设为 None 可禁用。
database_timezone str "UTC" 存储的日期时间所假定的时区。
timezone_switcher list[str] | None None 导航栏切换器中提供的时区。None 表示隐藏切换器。
use_user_locale_timezone bool True 优先使用根据用户区域设置推断出的时区,而非 default_timezone

要限制用户可选择的范围,请传入一个较短的 timezone_switcher 列表。要对所有查看者强制使用单一时区,请将 timezone_switcher 设为 None 并直接设置 default_timezone,例如全公司统一的 "Europe/Paris"

导航栏切换器通过 get_timezoneget_timezone_display_name 模板全局变量渲染每个时区的显示名称和 UTC 偏移量。模板指南对这些全局变量以及其他所有全局变量都有说明。


下一步:

  • 字段 DateTimeFieldArrowField 以及其余字段参考。
  • 模板 重写模板并直接使用 get_timezone 全局变量。
  • 概念 Admin 如何装配中间件和配置对象。