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 寻址限制等排障实录。
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 平台侧准备
- 已按《Weblate Docker Compose 部署指南》完成平台部署,
curl -s http://localhost:8143/healthz/返回ok; - 已创建至少一个项目与翻译组件(本文用
demo/demo/hello,可通过 Web 界面「+ 添加新翻译项目」或 REST API 创建); - 管理员可登录 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
七、注意事项
- wlc 全局参数必须前置:
wlc --format json stats demo/hello正确,wlc stats demo/hello --format json报unrecognized arguments(实测); - 语言代码一律用归一化代码:
zh_CN→zh_Hans、iw→he等,寻址报 Object not found 时先核对wlc --format csv list-languages中的 code 列; - API key 安全:key 等同账号权限,配置文件建议
chmod 600 ~/.config/weblate;经非本机 HTTP 传输 key 时 wlc 会要求显式确认(--allow-insecure-http),避免凭据明文过网; - 仓库操作命令无回显是正常行为(3.1.0 实测),成功与否用
wlc repo三旗标复核; - 管理命令路径固定:必须在部署目录下经编排进入主服务执行,直接在宿主机敲
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 说明。
九、参考链接
- wlc 官方文档:https://docs.weblate.org/en/latest/wlc.html
- REST API 文档:https://docs.weblate.org/en/latest/api.html
- 管理命令文档:https://docs.weblate.org/en/latest/admin/management.html
- 平台部署与编排运维:《Weblate Docker Compose 部署指南》
- 参数与限流:《Weblate 2026.10.1 配置参数详解》
- 平台认知:《Weblate 介绍与选型指南》