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

如何在Django中基于单一核心实现多站点部署?

在Django中通过单一核心与数据库管理多子路径站点

要实现一套代码+数据库管理所有子路径站点,可按以下步骤配置:

1. 路由拆分与分发

在项目根目录的urls.py中,将不同子路径的请求分发到对应子应用的路由模块,实现各站点路由隔离:

from django.urls import path, include

urlpatterns = [
    path('', include('main_site.urls')),  # 对应 example.com
    path('subdirectory1/', include('subdir1.urls')),  # 对应 example.com/subdirectory1
    path('subdirectory2/', include('subdir2.urls')),  # 对应 example.com/subdirectory2
    path('subdirectory2/en/', include('subdir2_en.urls')),  # 对应 example.com/subdirectory2/en
    path('subdirectory3/', include('subdir3.urls')),  # 对应 example.com/subdirectory3
]

每个子应用维护自己的urls.py,定义该站点的路由规则,避免路由冲突。

2. 数据隔离:通过站点标识区分数据

在需要跨站点隔离的模型中添加site_identifier字段,用来标记数据所属的站点:

from django.db import models

class Article(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()
    # 用固定值标记站点,比如'main'、'sub1'、'sub2'、'sub2_en'、'sub3'
    site_identifier = models.CharField(max_length=50)
    pub_date = models.DateTimeField(auto_now_add=True)

编写工具函数,根据请求路径识别当前站点标识:

def get_site_identifier(request):
    path_parts = request.path.strip('/').split('/')
    if not path_parts[0]:
        return 'main'
    elif path_parts[0] == 'subdirectory1':
        return 'sub1'
    elif path_parts[0] == 'subdirectory2':
        if len(path_parts) > 1 and path_parts[1] == 'en':
            return 'sub2_en'
        return 'sub2'
    elif path_parts[0] == 'subdirectory3':
        return 'sub3'
    return 'main'

在视图中使用该函数过滤对应站点的数据:

from django.views.generic import ListView
from .models import Article

class ArticleListView(ListView):
    model = Article
    
    def get_queryset(self):
        site_id = get_site_identifier(self.request)
        return super().get_queryset().filter(site_identifier=site_id)

3. 中间件注入站点标识

编写自定义中间件,将站点标识注入request对象,方便视图和模板全局使用:

from django.utils.deprecation import MiddlewareMixin
from .utils import get_site_identifier

class SiteIdentifierMiddleware(MiddlewareMixin):
    def process_request(self, request):
        request.site_identifier = get_site_identifier(request)

在settings.py的MIDDLEWARE列表中添加该中间件:

MIDDLEWARE = [
    # 其他中间件...
    'yourapp.middleware.SiteIdentifierMiddleware',
]

之后在模板中可以直接调用{{ request.site_identifier }}来区分站点资源。

4. 模板与静态文件区分

为每个站点创建独立的模板和静态文件目录:

  • 模板目录:templates/main_site/、templates/subdir1/、templates/subdir2/等
  • 静态文件目录:static/main_site/、static/subdir1/、static/subdir2/等

在视图中指定对应站点的模板:

class Subdir1HomeView(TemplateView):
    template_name = 'subdir1/home.html'

在模板中引用对应站点的静态文件:

{% load static %}
<link rel="stylesheet" href="{% static request.site_identifier %}/css/style.css">
<script src="{% static request.site_identifier %}/js/main.js"></script>

5. 管理后台统一管理

在Admin后台为模型添加站点标识筛选器,方便按站点管理数据:

from django.contrib import admin
from .models import Article

class ArticleAdmin(admin.ModelAdmin):
    list_display = ('title', 'site_identifier', 'pub_date')
    list_filter = ('site_identifier',)
    search_fields = ('title', 'content')

admin.site.register(Article, ArticleAdmin)

这样管理员可以在后台快速筛选、编辑不同站点的数据,无需切换系统。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 03:55:23