Wagtail 多站点与多实例架构怎么选?
2026/9/14 10:10:56 网站建设 项目流程

Wagtail 多站点与多实例架构怎么选?

【免费下载链接】wagtailA Django content management system focused on flexibility and user experience项目地址: https://gitcode.com/GitHub_Trending/wa/wagtail

当一个项目要用同一套 Wagtail 源码支撑多个网站时,官方文档给出两条落地路径:multi-site(多站点)——单服务器、单数据库、单媒体目录,内容可在站点间共享;multi-instance(多实例)——每个网站有独立的 settings 文件、独立数据库、独立媒体目录,各跑在自己的服务器进程里,内容完全隔离。选型的核心判据只有一条:你是否允许内容在站点之间共享,还是需要保证任何内容都不"泄漏"到另一个站点。本文基于 多站点与多实例说明 整理两种架构的工作机制、配置方式和各自的边界,帮助你按需求做出选择。

两种架构各自解决什么

Wagtail 项目文档对两种配置的定义:

  • Multi-site:内容创作者在一个后台里管理多个网站的内容。单代码库、单服务器、连一个数据库,媒体存放在单一的媒体根目录,内容可以在站点之间共享。权限可以做到"限定某些用户只能管理某个站点的内容",但无法做到按站点完全切分所有内容。
  • Multi-instance:一套项目文件被多个网站共用,每个网站有自己的 settings 文件、专用数据库和媒体目录,运行在自己的进程里。保证所有内容(含用户管理)的完全隔离,代价是站点间不能共享内容。

文档明确指出:如果项目要求编辑者只能在特定站点操作、且要完全隔离内容,"把全部内容按站点切分并保证没有泄漏"在多站点项目里很难实现,此时 multi-instance 更合适。反之,如果需要像多站点那样共享内容,multi-instance 就做不到。

另外需要提前了解:Wagtail 目前不支持完整的 multi-tenancy(单实例 + 内容按租户完全隔离 + 独立用户管理)。多实例配置是 Wagtail 能接近"真多租户"的最远形态——"新增一个租户"就是新增一个 settings 文件并跑一个新实例。

多站点:靠 Site 模型把域名映射到页面树

Wagtail 开箱支持 multi-site,核心是 Site 模型(wagtail.models.Site)。它包含:

  • hostname:站点主机名(不含协议、端口和路径,如www.mysite.com);
  • port:站点响应的端口;
  • site_name:人类可读的站点名,Wagtail 自身不使用,适合展示在前端如<title>中;
  • root_page:指向站点根页面的外键,该页面出现在站点的/URL 上;
  • is_default_site:默认站点标志,有且只能有一个,作为找不到匹配 hostname/端口时的兜底。

工作机制:请求进来后,Wagtail 从请求对象取出域名和端口,查找对应的 Site 对象(Site.find_for_request),再以它的根页面为起点解析 URL、返回正确的页面。模型对象想绑定到某个站点时,可以在模型上加一个指向 Site 的外键字段,并用 request 对象查当前站点,从而只输出属于该站点的内容。

站点级配置用 site settings 实现

Wagtail 自带 site settings(wagtail.contrib.settings):继承BaseSiteSetting的模型就是"绑定到某个站点的单例配置",可存社交账号、logo、主题选择等站点私有信息。通用配置则继承BaseGenericSetting。使用步骤:

INSTALLED_APPS += [ "wagtail.contrib.settings", ]
from django.db import models from wagtail.contrib.settings.models import ( BaseGenericSetting, BaseSiteSetting, register_setting, ) @register_setting class GenericSocialMediaSettings(BaseGenericSetting): facebook = models.URLField() @register_setting class SiteSpecificSocialMediaSettings(BaseSiteSetting): facebook = models.URLField()

链接会出现在 Wagtail 后台的 Settings 菜单里。在视图中取当前请求对应站点的配置:

def view(request): social_media_settings = SiteSpecificSocialMediaSettings.for_request(request=request)

在模板中取站点配置需要加上下文处理器wagtail.contrib.settings.context_processors.settings,然后用{{ settings.app_label.SiteSpecificSocialMediaSettings.facebook }}访问(app_label替换为你放置设置模型的应用标签)。注意文档的提醒:模板里如果没有 request 对象,就无法可靠地取到当前站点的配置——{% get_settings %}标签在无RequestContext时只能退回默认站点,这对多站点部署是关键限制。

权限如何按站点收敛

多站点下的权限手段:

  • 用户、组、权限可以配置成让内容创作者只能管理某个站点的页面、图片和文档;
  • 权限可以挂到某个页面树的特定层级或子集;
  • Collection 用于归类图片和文档,集合可以限制为只有特定组的用户可访问。

再次强调边界:这是"部分程度"的隔离。站点间共享同一数据库,无法保证任何内容绝对不泄漏。

多实例:一套代码,每站一个 settings 文件加一个进程

Multi-instance 的做法是:所有站点共用同一份项目文件,差异只写在 settings 文件里。假设站点 a.com 和 b.com,settings 目录可以组织为base.pyacom.pybcom.py,站点文件from base import *后覆盖关键项:

# settings/acom.py from base import * # noqa ALLOWED_HOSTS = ['a.com'] DATABASES["NAME"] = "acom" DATABASES["PASSWORD"] = "password-for-acom" MEDIA_DIR = BASE_DIR / "acom-media"

(以上为文档示例,具体变量名以你的项目为准。)

启动方式:

  • 开发环境:每个站点用自己的 settings 文件启动,如./manage.py runserver --settings settings.acom
  • 生产环境:以 uWSGI 为例,用env = DJANGO_SETTINGS_MODULE=settings.acom指定正确的 settings。

部署时只更新这一份项目文件,然后 reload 每个实例。因为每个站点有独立的数据库和媒体目录,任何内容都不可能泄漏到别的站点——但也因此不能像多站点那样共享内容。

多实例的资源代价

文档明确提醒:多实例配置下每个实例都要占用一定的服务器资源(CPU 和内存),加站点就会增加服务器负载,这种扩展方式只能撑到一定程度。如果你的"多站点"数量会持续增长,这一点必须在选型时计入。

怎么选:按需求对号入座

需求文档给出的对应方案
一个后台管理多个网站,内容可以共享Multi-site(Site 模型 + site settings,开箱即用)
站点间内容、用户必须完全隔离Multi-instance(每站独立 settings 文件、数据库、媒体目录、进程)
单实例 + 按租户完全隔离内容与用户当前不支持完整 multi-tenancy,文档建议用 multi-instance 逼近,或基于下述扩展点自建

如果目标是"类多租户",文档列出了 Wagtail 目前已有的支撑能力和明确的缺口:

已支持:

  • Site 模型把 hostname 映射到根页面;
  • 权限允许用户组管理页面树的任意区段、文档和图像的集合(集合树的区段权限"coming soon");
  • 页面 API 会按请求所用 host 自动限定作用范围。

暂不支持多租户、需要自行处理的部分:

  • Snippets 是全局内容,天然不适合按租户隔离。文档给出的绕法是:模型上加site_id字段,用 model admin 的get_queryset决定哪个站点能管理哪些对象;
  • Site、site setting、用户和组的管理:权限不是站点级的,任何有编辑权限的用户可以编辑所有条目。文档建议这些对象只允许 superuser 管理;
  • 工作流与工作流任务;站点历史;重定向(Redirects)。

Python/Django/Wagtail 允许覆盖和扩展行为,文档提到的自建方向包括:Django 模板覆盖(对 Wagtail 后台同样有效)、用自定义用户模型把用户绑定到特定站点、用自定义后台视图提供更严格的用户管理。

验证与后续检查

选择架构后,可以按文档描述的行为核对是否生效:

Multi-site:用不同 hostname 请求服务,确认Site.find_for_request命中对应的 Site 对象,且返回的页面以该站点的root_page为起点解析;找不到匹配 hostname/端口时请求落到is_default_site指向的默认站点。模板中依赖 request 的站点配置(site settings)在带请求的上下文中取到的是当前站点的值——若某处取回的是默认站点值,先检查该上下文是否缺少 request。

Multi-instance:确认每个进程确实加载了各自的DJANGO_SETTINGS_MODULE(开发环境看runserver --settings参数,uWSGI 看env配置),各站点的数据库名、媒体目录互不相同;更新项目文件后逐个 reload 实例,确认所有站点都运行在新代码上。

已知限制汇总

  • Multi-site 无法保证按站点完全隔离内容,"保证不泄漏"很难实现;
  • Multi-instance 中站点间不能共享内容,且实例数受服务器 CPU/内存上限约束;
  • 完整 multi-tenancy 当前不支持;site settings 在模板中依赖 request 才能定位到正确站点;snippets、Site/用户/组管理、工作流、站点历史、重定向均未按多租户设计。

如果当前只是"一个团队、多个域名、内容可共享",multi-site 是文档描述的默认路径,配置量最小;只有当隔离是硬性要求时才承担 multi-instance 的额外运维成本。

【免费下载链接】wagtailA Django content management system focused on flexibility and user experience项目地址: https://gitcode.com/GitHub_Trending/wa/wagtail

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询