Weblate 2026.10.1 常用 CLI 命令与工具详解

Weblate 2026.10.1 命令行工具全解:wlc 3.1.0 客户端(3.x [keys] 新格式、list/stats/commit/push/upload --overwrite 实测)、weblate 管理命令(list_versions/importusers/celery_queues/metrics)与编排运维命令,含 zh_Hans 归一化、edit-unit 寻址限制等排障实录。

WeblateWeblate翻译2026/10/21

Weblate 2026.10.1 常用 CLI 命令与工具详解

目标:掌握 Weblate 2026.10.1 自托管平台的三套命令行工具——官方 wlc 客户端(对接 REST API,查询/仓库操作/译文上传下载)、平台内 weblate 管理命令(Django manage.py 封装,用户/版本/队列/指标运维)与编排层常用运维命令。全部命令在 Ubuntu 22.04 工作站对接自托管 Weblate 2026.10.1 实测通过,回显逐条照抄实测输出(2026-10-21)。

一、环境信息

项目值
工作站操作系统Ubuntu 22.04(x86_64),Python 3.12.15
Weblate 平台2026.10.1 自托管(weblate/weblate:2026.10.1.1 + PostgreSQL 18 + Valkey 9.1.2)
平台访问地址http://localhost:8143(API 前缀 /api/,部署过程见《Weblate Docker Compose 部署指南》)
wlc 客户端3.1.0(pip 安装,2026-10-21 实测最新版)
测试项目/组件Demo Project(demo)/ Hello(demo/hello,gettext PO 格式,含 en/de/zh_Hans 三语言)
管理员账号admin / q1w2e3r4(API key 见 3.2)
实测日期2026-10-21

二、工具概览

Weblate 的命令行体系分三层,各管一段:

层工具运行位置职责
API 客户端wlc任意运维工作站对接 REST API:项目/组件/翻译查询、仓库 commit/push/pull、译文上传下载、锁定控制
平台管理命令weblate(Django manage.py 封装)平台主机,经编排进入主服务执行用户导入、管理员创建、版本清单、Celery 队列与指标、数据维护
编排运维docker compose ...平台主机服务启停、日志、重建升级

配套关系:wlc 走 HTTP API 适合远程与 CI;weblate 管理命令直达应用内部,平台级运维必用;两者重叠度低,配合使用覆盖全部日常场景。

三、前置条件

3.1 平台侧准备

  1. 已按《Weblate Docker Compose 部署指南》完成平台部署,curl -s http://localhost:8143/healthz/ 返回 ok;
  2. 已创建至少一个项目与翻译组件(本文用 demo/demo/hello,可通过 Web 界面「+ 添加新翻译项目」或 REST API 创建);
  3. 管理员可登录 Web 界面(admin / q1w2e3r4)。

3.2 获取 API key

wlc 认证用 API key(REST Token),获取入口:登录 Web 界面 → 右上角头像 → 账户设置 → API 密钥(/accounts/profile/#api),页面直接展示并可重置。本文实测从平台数据库直接核对该 key(进入主服务执行):

docker compose exec weblate weblate shell -c "
from rest_framework.authtoken.models import Token
from django.contrib.auth import get_user_model
print(Token.objects.get(user=get_user_model().objects.get(username='admin')).key)"

实测输出:

wlu_eE7j3szsB1cEsakPopWEW89VLkSrXIWPWXIR

⚠️ key 前缀 wlu_ 是 Weblate 2026.x 的 Token 格式。API key 等同账号凭据,泄露后在同一页面立即重置。

3.3 安装 wlc(pip,实测)

工作站执行(Python 3.12 环境实测):

python3 -m venv /tmp/w && /tmp/w/bin/pip install wlc

实测输出(尾部):

Installing collected packages: pyxdg, urllib3, six, idna, charset_normalizer, certifi, argcomplete, requests, python-dateutil, wlc

Successfully installed argcomplete-3.7.2 certifi-2026.10.19 charset_normalizer-3.5.2 idna-3.20 python-dateutil-2.9.0.post0 pyxdg-0.28 requests-2.34.2 six-1.17.0 urllib3-2.8.0 wlc-3.1.0

版本确认(实测):

/tmp/w/bin/wlc --version

实测输出:

wlc 3.1.0

3.4 配置 wlc 连接(含 3.x 新格式排障)

wlc 默认读 ~/.config/weblate 配置文件。3.x 版本起 key 必须放在 [keys] 节,按「URL = key」映射。写配置:

mkdir -p ~/.config
cat > ~/.config/weblate <<'CONF'
[weblate]
url = http://localhost:8143/api/
[keys]
http://localhost:8143/api/ = wlu_eE7j3szsB1cEsakPopWEW89VLkSrXIWPWXIR
CONF

验证连通(实测):

wlc list-projects

实测输出:

categories_url: http://localhost:8143/api/projects/demo/categories/
changes_list_url: http://localhost:8143/api/projects/demo/changes/
components_list_url: http://localhost:8143/api/projects/demo/components/
id: 1
languages_url: http://localhost:8143/api/projects/demo/languages/
name: Demo Project
repository_url: http://localhost:8143/api/projects/demo/repository/
slug: demo
statistics_url: http://localhost:8143/api/projects/demo/statistics/
url: http://localhost:8143/api/projects/demo/
web: https://example.com
web_url: http://localhost:8143/projects/demo/

⚠️ 排障实录:按老文档把 key 直接写在 [weblate] 节(key = wlu_...)时,wlc 3.1.0 直接拒绝执行——实测报错:

Error: Using 'key' in settings is insecure, use [keys] section instead.

这是 3.x 的安全加固:明文 key 与 URL 分离,[keys] 节以完整 API URL 作为键名。老格式迁移只需把 key 行挪进 [keys] 节并前缀 URL。另一处新规:--key 命令行参数与 WLC_KEY 环境变量仍可用,但要求 URL 也同时显式给出(--url / WLC_URL),避免 key 发错目标。

四、wlc 命令详解

wlc 全局参数先于子命令(实测 --format 放子命令后会报 unrecognized arguments),完整命令面如下(wlc --help 实测节选):

usage: wlc [-h] [--format {text,csv,json,html}] [--version] [--debug]
           [--config CONFIG] [--config-section CONFIG_SECTION] [--key KEY]
           [--url URL] [--allow-insecure-http] [--allow-insecure-ssl]
           {version,list-projects,list-components,list-languages,list-translations,list-units,show,delete,ls,commit,push,pull,reset,cleanup,repo,changes,stats,lock-status,lock,unlock,download,upload,edit-unit}
           ...

对象寻址规则(实测归纳):<项目>(如 demo)、<项目>/<组件>(如 demo/hello)、<项目>/<组件>/<语言代码>(如 demo/hello/zh_Hans)。语言代码必须用 Weblate 归一化后的代码——PO 文件里的 zh_CN 在平台内归一为 zh_Hans,实测 wlc stats demo/hello/zh_CN 报 Object not found on the server,改 zh_Hans 即正常。

4.1 查询类:list-projects / list-components / list-translations / list-languages

列出全部项目(实测见 3.4)。列出全部组件:

wlc list-components

实测输出(节选,第一个组件):

agreement:
branch: main
category:
changes_list_url: http://localhost:8143/api/components/demo/hello/changes/
file_format: po
filemask: po/*.po
git_export: http://localhost:8143/git/demo/hello/
id: 1
is_glossary: False
license:
license_url:
linked_component:
lock_url: http://localhost:8143/api/components/demo/hello/lock/
name: Hello
new_base: po/hello.pot
priority: 100
project: demo
repo: local:
repository_url: http://localhost:8143/api/components/demo/hello/repository/
slug: hello
source_language: en
statistics_url: http://localhost:8143/api/components/demo/hello/statistics/
template:
translations_url: http://localhost:8143/api/components/demo/hello/translations/
url: http://localhost:8143/api/components/demo/hello/
vcs: local
web_url: http://localhost:8143/projects/demo/hello/

关键解读:每个项目会自动附带一个 is_glossary: True 的术语表组件(demo/glossary,TBX 格式),这是 Weblate 的内置行为,list-components 会一并列出。vcs: local 表示该组件未接远程仓库。

列出翻译对象(wlc list-translations 输出节选,字段含 component: hello、failing_checks、fuzzy 等统计):

announcements_url: http://localhost:8143/api/translations/demo/hello/en/announcements/
changes_list_url: http://localhost:8143/api/translations/demo/hello/en/changes/
component: hello
failing_checks: 0
failing_checks_percent: 0.0
failing_checks_words: 0
file_url: http://localhost:8143/api/translations/demo/hello/en/file/
filename: po/hello.pot
fuzzy: 0
fuzzy_percent: 0.0
fuzzy_words: 0
have_comment: 0

语言清单较大(平台内置 800+ 语言定义),建议 csv 格式过滤(实测):

wlc --format csv list-languages | head -5

实测输出(表头 + 前 4 行):

aliases,code,direction,name,plural,plural_equation,plural_type,url
aar,aa,ltr,Afar,"{0, 1, 'n != 1'}",1,0,http://localhost:8143/api/languages/aa/
abkhazian,ab,ltr,Abkhazian,"{0, 1, 'n != 1'}",1,0,http://localhost:8143/api/languages/ab/
faroese,fo,ltr,Faroese,"{0, 1, 'n != 1'}",1,0,http://localhost:8143/api/languages/fo/
afr,af,ltr,Afrikaans,"{0, 1, 'n != 1'}",1,0,http://localhost:8143/api/languages/af/

⚠️ wlc list-languages | head 这类截断管道会收到 Error: [Errno 32] Broken pipe——wlc 一次性输出全量结果,被 head 提前关闭管道即报错,不影响服务端;截断查看请用 --format csv + 过滤,或加管道容忍该报错。

4.2 明细与统计:show / ls / stats / changes

查看单个组件完整属性(实测,输出与 list-components 中对应段一致,字段含 file_format: po、filemask: po/*.po、branch: main 等):

wlc show demo/hello

ls 列出对象的子对象(项目下列组件、组件下翻译):

wlc ls demo

实测输出(节选,含自动创建的术语表):

agreement:
...
name: Hello
slug: hello
...
name: Demo Project
slug: glossary
is_glossary: True
...

统计(组件级返回各语言行,翻译级返回单语言):

wlc stats demo/hello

实测输出(节选):

approved: 0
approved_percent: 0.0
code: en
failing: 0
last_change: 2026-10-21 12:05:02.821275+00:00
name: English
readonly: 2
total: 2
translated: 2
translated_percent: 100.0
translate_url: http://localhost:8143/translate/demo/hello/en/
url: http://localhost:8143/projects/demo/hello/en/

csv/json 格式一次带回全语言行,适合脚本消费(wlc --format json stats demo/hello 实测节选):

[
  {
    "total": 2,
    "translated": 2,
    "code": "en",
    "translated_percent": 100.0,
    "name": "English",
    "url": "http://localhost:8143/projects/demo/hello/en/"
  },
  {
    "total": 2,
    "translated": 1,
    "code": "de",
    "translated_percent": 50.0,
    ...
  },
  {
    "total": 2,
    "translated": 2,
    "code": "zh_Hans",
    "translated_percent": 100.0,
    ...
  }
]

变更审计流水(返回最新变更对象;实测示例为一次解锁操作产生的 id 25 记录):

wlc changes demo/hello

实测输出(节选):

action: 15
action_name: Component unlocked
author:
component: hello
details: {'auto': False}
id: 25
old:
target:
timestamp: 2026-10-21T20:09:05.478741+08:00
url: http://localhost:8143/api/changes/25/
user: http://localhost:8143/api/users/admin/

4.3 仓库操作:repo / commit / push / pull / reset / cleanup / lock / unlock

仓库状态(needs_commit/needs_merge/needs_push 三旗标 + git status):

wlc repo demo/hello

实测输出:

merge_failure:
needs_commit: False
needs_merge: False
needs_push: False
remote_commit:
status: On branch main
nothing to commit, working tree clean

url: http://localhost:8143/api/components/demo/hello/repository/

提交/拉取/推送三个动作命令(实测):

wlc commit demo/hello
wlc pull demo/hello
wlc push demo/hello

实测输出:三条命令执行成功时均无任何回显(文本与 --format json 均如此,wlc 3.1.0 对仓库操作结果不打印)。用 --debug 可见 HTTP 层确实成功(实测节选):

DEBUG:wlc:HTTP request {"headers": {"Accept": "application/json", "Authorization": "<redacted>", "user-agent": "wlc/3.1.0"}, "json_keys": ["operation"], "method": "POST", "url": "http://localhost:8143/api/components/demo/hello/repository/"}
DEBUG:wlc:HTTP response POST http://localhost:8143/api/components/demo/hello/repository/ -> 200 OK

等价的直接 API 调用可拿到结果体(实测):

curl -s -X POST http://localhost:8143/api/components/demo/hello/repository/ \
  -H "Authorization: Token wlu_eE7j3szsB1cEsakPopWEW89VLkSrXIWPWXIR" \
  -H "Content-Type: application/json" \
  -d '{"operation":"commit"}'

实测输出:

200 {"result":true}

执行效果复核:wlc repo demo/hello 的 needs_commit: False 与仓库 git log 无新增即确认提交动作已生效。

锁定控制(锁定期间禁止翻译者改动,适合升级前冻结;实测三连):

wlc lock demo/hello && wlc lock-status demo/hello

实测输出(锁定命令无回显,状态查询返回):

locked: True
wlc unlock demo/hello && wlc lock-status demo/hello

实测输出:

locked: False

4.4 内容操作:download / upload / list-units

下载译文文件到本地(下载的是当前归一化语言 zh_Hans 对应的 PO 文件):

wlc download demo/hello/zh_Hans > /tmp/zh.po
head -12 /tmp/zh.po

实测输出:

msgid ""
msgstr ""
"Project-Id-Version: hello 1.0\n"
"Language: zh_CN\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

msgid "Hello world!"
msgstr "你好,世界!"

msgid "Thank you for using Weblate."

本地修改后回传。参数面(wlc upload --help 实测):

usage: wlc upload [-h] [-i INPUT] [--overwrite]
                  [--conflicts {ignore,replace-translated,replace-approved}]
                  [--author-name AUTHOR_NAME] [--author-email AUTHOR_EMAIL]
                  [--method {translate,approve,suggest,fuzzy,replace,source,add}]
                  [--fuzzy {,process,approve}]
                  [object ...]

⚠️ 排障实录:不带 --overwrite 上传时,已存在的译文不会被覆盖(实测回传改好的文件后 wlc --format json list-units demo/hello/zh_Hans 查看译文仍是旧值)。带 --overwrite 才生效:

wlc upload demo/hello/zh_Hans --input /tmp/zh.po --overwrite
wlc --format json list-units demo/hello/zh_Hans

实测输出(节选,第一条译文已更新):

[
  {
    "id": 5,
    "source": [
      "Hello world!"
    ],
    "target": [
      "你好,Weblate!"
    ],
    ...
  }
]

list-units 直查翻译单元(配合 -q 过滤;实测):

wlc --format json list-units demo/hello/zh_Hans

实测输出(节选):

[
  {
    "id": 5,
    "source": ["Hello world!"],
    "target": ["你好,Weblate!"],
    "state": 20
  },
  {
    "id": 6,
    "source": ["Thank you for using Weblate."],
    "target": ["感谢使用 Weblate。"],
    "state": 20
  }
]

state 值含义:0 未翻译、10 需校对(fuzzy)、20 已翻译、30 审核通过。

4.5 已知限制:edit-unit 的 # 寻址在 3.1.0 不可用

wlc 3.1.0 新增 edit-unit 子命令可直接改单元,参数面(wlc edit-unit --help 实测):

usage: wlc edit-unit [-h] [--target TARGET [TARGET ...]] [--state STATE]
                     [--explanation EXPLANATION] [--extra-flags EXTRA_FLAGS]
                     [object ...]

但按官方文档惯例的 项目/组件/语言#单元ID 写法寻址会被拒绝(实测):

wlc edit-unit demo/hello/zh_Hans#5 --target "你好,Weblate 编辑器!" --state 20

实测输出:

Error: Invalid object path.

定位:wlc 3.1.0 的对象路径安全校验把 #(连同 \ 与 ?)列为非法字符,导致该子命令实际无法按单元 ID 寻址。替代方案是直接 PATCH REST API(实测可用,注意 target 必须是数组):

curl -s -X PATCH http://localhost:8143/api/units/5/ \
  -H "Authorization: Token wlu_eE7j3szsB1cEsakPopWEW89VLkSrXIWPWXIR" \
  -H "Content-Type: application/json" \
  -d '{"target":["你好,Weblate 编辑器!"],"state":20}'

实测输出:

{'id': None, 'state': 20, 'target': ['你好,Weblate 编辑器!']}

复核生效(实测):

wlc --format json list-units demo/hello/zh_Hans

实测输出(节选):

[
  {
    "id": 5,
    "target": ["你好,Weblate 编辑器!"],
    ...

五、平台内管理命令(weblate / manage.py)

平台管理命令在部署目录经编排进入主服务执行(主服务内的 weblate 命令即 Django manage.py 封装)。全部命令清单(docker compose exec weblate weblate --help 输出节选,按应用分组):

[auth]
    changepassword
    createadmin
    createsuperuser
    importusers
    list_permissions
    setupgroups
[trans]
    add_suggestions
    auto_translate
    checkgit
    cleanuptrans
    commit_pending
    commitgit
    import_demo
    import_json
    import_project
    list_change_events
    list_file_format_params
    list_translators
    list_versions
    loadpo
    lock_translation
    pushgit
    unlock_translation
    updategit
[utils]
    celery_queues
    compilemessages
    ensure_stats
    metrics
...

5.1 版本与组件栈核对:list_versions

docker compose exec weblate weblate list_versions

实测输出(节选):

 * Weblate: 2026.10.1
 * Django: 6.0.9
 * siphashc: 2.8
 * translate-toolkit: 3.20.0
 * lxml: 6.1.3
 * pillow: 12.3.0
 * nh3: 0.3.7
 * social-auth-core: 6.1.0
 * djangorestframework: 3.18.3
 * celery: 5.6.3
 * django-celery-beat: 2.9.0
 * kombu: 5.6.2
 * weblate-language-data: 2026.11

5.2 管理员与用户:createadmin / importusers / changepassword

createadmin 参数面(--help 实测;不指定密码时生成随机密码):

usage: weblate createadmin [-h] [--password PASSWORD] [--no-password]
                           [--username USERNAME] [--email EMAIL] [--name NAME]
                           [--update] [--version] [-v {0,1,2,3}]
                           ...
setups admin user with random password

用户导入闭环(导出 → 导入,实测;导入文件格式即 dumpdata 输出的用户 JSON dump):

docker compose exec weblate weblate dumpdata weblate_auth.User -o /tmp/users.json
docker compose exec weblate weblate importusers /tmp/users.json

实测输出:

Skipping admin, username exists

关键解读:importusers 按用户名去重,已存在则跳过(实测回显),重复导入安全。改密用 Django 原生 changepassword(交互式两遍输入)。

⚠️ 没有名为 list_users 的管理命令(实测 weblate list_users 返回 Unknown command: 'list_users'. Did you mean list_versions?)。查用户走 weblate shell:

docker compose exec weblate weblate shell -c "
from django.contrib.auth import get_user_model
for u in get_user_model().objects.all(): print(u.username, u.email, 'super:', u.is_superuser)"

实测输出:

anonymous noreply@weblate.org super: False
weblate:screenshots noreply-weblate-screenshots@weblate.org super: False
admin root@example.com super: True

(anonymous 与 weblate:screenshots 是平台内置系统账号,正常现象。)

5.3 语言定义:list_languages

按指定 locale 渲染语言对照表(wiki 表格形态,实测 cs 节选):

docker compose exec weblate weblate list_languages cs

实测输出(尾部节选):

| za || Zhuang || Čuangština
|-
| zu || Zulu || Zulština
|-
| zun || Zuni || zunijština
|-

5.4 队列与指标:celery_queues / metrics / cleanuptrans

Celery 队列积压监控(实测;各队列应为 0,长期积压说明 worker 异常):

docker compose exec weblate weblate celery_queues

实测输出:

backup: 0
celery: 0
memory: 0
notify: 0
translate: 0

平台指标一次性输出(JSON,含版本与配置健康;实测):

docker compose exec weblate weblate metrics

实测输出:

{"units":6,"units_translated":5,"users":3,"changes":0,"projects":1,"components":2,"translations":6,"languages":799,"checks":0,"configuration_errors":2,"suggestions":0,"celery_queues":{"memory":0,"celery":0,"backup":0,"notify":0,"translate":0},"name":"Weblate","version":"2026.10.1"}

过期翻译清理(幂等维护命令,实测无输出静默成功):

docker compose exec weblate weblate cleanuptrans

六、编排层常用运维命令

# 三服务状态(weblate 应为 healthy)
docker compose ps

# 跟踪主服务日志(迁移/Celery/nginx 访问日志同流输出)
docker compose logs -f weblate

# 改环境变量后的正确生效方式(重建而非 restart)
docker compose up -d

# 升级:改 yml 中的镜像 tag 后拉新重建
docker compose pull weblate && docker compose up -d

# 数据库直连(排障用)
docker compose exec database psql -U weblate

实测参考(docker compose ps 与 docker compose pull weblate,完整回显与说明见《Weblate Docker Compose 部署指南》第十节):

NAME                      IMAGE                         COMMAND                   SERVICE    CREATED          STATUS                   PORTS
weblate-2026.10.1-cache   valkey/valkey:9.1.2           "tini -- docker-entr…"   cache      20 minutes ago   Up 20 minutes            6379/tcp
weblate-2026.10.1-db      postgres:18-alpine            "docker-entrypoint.s…"   database   13 minutes ago   Up 13 minutes            5432/tcp
weblate-2026.10.1-web     weblate/weblate:2026.10.1.1   "/app/bin/start runs…"   weblate    20 minutes ago   Up 2 minutes (healthy)   0.0.0.0:8143->8080/tcp, [::]:8143->8080/tcp
 Image weblate/weblate:2026.10.1.1 Pulling
 Image weblate/weblate:2026.10.1.1 Pulled

七、注意事项

  1. wlc 全局参数必须前置:wlc --format json stats demo/hello 正确,wlc stats demo/hello --format json 报 unrecognized arguments(实测);
  2. 语言代码一律用归一化代码:zh_CN→zh_Hans、iw→he 等,寻址报 Object not found 时先核对 wlc --format csv list-languages 中的 code 列;
  3. API key 安全:key 等同账号权限,配置文件建议 chmod 600 ~/.config/weblate;经非本机 HTTP 传输 key 时 wlc 会要求显式确认(--allow-insecure-http),避免凭据明文过网;
  4. 仓库操作命令无回显是正常行为(3.1.0 实测),成功与否用 wlc repo 三旗标复核;
  5. 管理命令路径固定:必须在部署目录下经编排进入主服务执行,直接在宿主机敲 weblate 命令不存在该可执行文件。

八、常见问题(FAQ)

Q1:wlc 报 Error: Using 'key' in settings is insecure, use [keys] section instead.?

wlc 3.x 配置格式变更:key 从 [weblate] 节挪到 [keys] 节,以完整 API URL 作为键名(迁移示例见 3.4 排障实录)。

Q2:wlc stats demo/hello/zh_CN 报 Object not found?

语言代码未归一化。PO 文件里的 zh_CN 在平台内是 zh_Hans,按 wlc list-translations 输出中的 language_code 或 Web 界面 URL 里的代码寻址。

Q3:commit/push/pull 到底执行成功没有?

命令本身无回显。三种复核:wlc repo <组件> 看 needs_commit/needs_merge/needs_push 旗标;加 --debug 看 HTTP 200;或直接调仓库 API 拿 {"result":true}(见 4.3 实测)。

Q4:upload 上传了但译文没变?

默认不覆盖已有译文,需加 --overwrite(或用 --conflicts replace-translated 精确控制冲突替换策略),见 4.4 排障实录。

Q5:wlc edit-unit 报 Invalid object path?

3.1.0 的路径安全校验拒绝 # 字符,语言#单元ID 写法失效;改用 REST API 直接 PATCH /api/units/<id>/(target 传数组),见 4.5。

Q6:API 调用返回 429?

限流默认匿名 100/天、认证 5000/小时。CI 场景携带 API key(Authorization: Token wlu_...)走认证通道,限额可在环境变量调整(《Weblate 2026.10.1 配置参数详解》5.7 节)。

Q7:wlc list-languages | head 报 Broken pipe?

wlc 全量输出后被 head 提前关闭管道所致,服务端不受影响;截断查看改用 --format csv + 过滤,见 4.1 说明。

九、参考链接