You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于单数据库创建路径区分的Django 3多站点?

Django 3 单域名多子路径共库站点部署最佳实践

整个方案基于单项目多APP架构实现,不需要部署多个Django实例,维护成本最低,完全匹配子路径访问、共库、公共内容复用的需求。

1. 项目结构拆分

  • 根路径主站点单独创建core APP承载,每个子路径站点(website1到websiteN)分别独立创建对应APP,比如web1、web2,后续新增站点直接新建APP即可
  • 所有跨站点复用的公共能力(公共模型、模板组件、工具函数、静态资源、通用视图)全部抽离到独立的common APP中,禁止把公共代码散落在各个站点APP里
  • 所有APP统一注册到INSTALLED_APPS列表,共用同一份settings配置,不需要维护多套配置文件

共库注意事项:所有模型统一迁移到同一个数据库,不需要配置多数据库路由。公共表(用户表、全局配置、公共内容块等)全部放在common APP下生成迁移文件,各站点独有模型放在自身APP下生成迁移文件,统一执行python manage.py makemigrations和python manage.py migrate即可,只要不同APP的模型不重名就不会出现表冲突。

2. 路由配置(核心匹配规则)

直接在项目根路由表中按路径前缀挂载各个站点的路由即可,注意路由顺序,避免子站请求被主站兜底路由拦截:

# 项目根目录urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    # 先挂载所有子站点路由
    path('website1/', include('web1.urls')),
    path('website2/', include('web2.urls')),
    # 新增子站只需要在这里加一行对应路由即可
    # path('website_n/', include('webn.urls')),
    # 最后挂载主站路由
    path('', include('core.urls')),
]

注意:子站点APP内部的路由全部写相对路径即可,比如web1中配置path('about/', about_view),实际访问路径就是main_domain.com/website1/about/,不需要在子APP路由里重复写website1前缀。

3. 公共内容复用实现

分四个层面落地,完全避免重复开发:

  • 公共数据复用:公共模型(通用文章、广告位、友链、全局配置等)全部定义在common APP的models.py中,各站点直接导入调用即可,不需要重复建表。可以给公共模型加site_tag字段,标记内容是全站点通用还是归属某个子站,各站点按需过滤数据即可。
  • 公共模板复用:在项目根目录创建统一的templates目录,内部按common(公共页头、页脚、导航、分页组件等片段)、core(主站模板)、web1/web2(子站模板)分子目录,在TEMPLATES配置中把根templates目录加入DIRS列表,子站模板直接通过{% include 'common/header.html' %}引入公共片段即可,公共模板预留block块支持子站做差异化覆盖。
  • 公共静态资源复用:根目录创建统一的static目录,内部按common(公共css、js、图片、字体)、core、web1/web2分子目录存放资源,模板中引用公共资源直接写{% static 'common/css/global.css' %}即可,不需要每个站点重复存储一份公共资源。
  • 公共逻辑复用:通用登录校验、列表分页逻辑、文件上传能力、异常处理等全部写在common APP的utils.py或者通用视图中,各站点直接导入调用、或继承通用视图即可,不需要重复编写相同逻辑。

4. 部署与站点识别方案

  • 部署层面只需要启动一个Django进程(搭配Gunicorn/uWSGI均可),Nginx把所有请求统一转发给该进程,静态资源执行python manage.py collectstatic统一收集到同一个目录由Nginx托管,不需要为每个子路径单独配置转发或静态资源规则。
  • 子站点差异化配置识别不需要引入Django自带的sites框架(该框架适配多域名场景,当前场景用反而增加复杂度),自己写一个轻量中间件即可实现当前站点配置注入:
# common/middleware.py
# 维护各站点的差异化配置,比如站点名、备案号、logo路径等
SITE_MAPPING = {
    '': {'site_name': '主站', 'icp': '京ICP备xxx号-1'},
    'website1': {'site_name': '站点1', 'icp': '京ICP备xxx号-2'},
    'website2': {'site_name': '站点2', 'icp': '京ICP备xxx号-3'},
}

class SiteIdentifyMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        # 提取请求路径第一段作为站点匹配标识
        path_prefix = request.path.strip('/').split('/')[0]
        # 绑定当前站点配置到request对象,所有视图、模板可直接调用
        request.current_site = SITE_MAPPING.get(path_prefix, SITE_MAPPING[''])
        return self.get_response(request)

写完把该中间件加入settings的MIDDLEWARE列表即可生效。

后续新增子站点的流程非常固定:新建对应APP→编写站点独有逻辑和模板→根路由添加一行挂载配置→在站点映射字典中加对应差异化配置,最快十几分钟就能完成一个新站上线,公共能力直接复用不需要重复开发。

内容的提问来源于stack exchange,提问作者Darwin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 12:57:11