如何在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
相关产品推荐
相关产品推荐

