Django: 如何根据URL动态设置settings.py中的SITE_ID?
有什么好的方法可以根据网址中的域名动态设置settings.py里的SITE_ID吗?
我有一个应用程序,它会在很多不同的域名下运行(根据城市来区分),所以为每个域名单独写一个settings.py文件根本不现实。
有没有办法可以动态设置这个值呢?
3 个回答
0
这个方法适用于Django 3.2版本。
这段代码和之前的回答差不多,所以我就不详细解释它是怎么工作的了。不过,我觉得在3.2版本中,写自定义中间件的方式稍微有点变化。主要的不同在于要继承MiddleWareMixin。我把这段代码放在middleware.py文件里,然后在settings.py的MIDDLEWARE列表中添加它。
与之前的回答相比,第二个变化是直接从settings.py中使用SITE_ID,而不是使用DEFAULT_SITE_ID,因为我觉得在settings.py中同时设置这两个没有必要。
# middleware.py
class DynamicSiteMiddleware(MiddlewareMixin):
"""
Make all domain names available through request.site
"""
def process_request(self, request):
try:
current_site = Site.objects.get(domain=request.get_host())
except Site.DoesNotExist:
current_site = Site.objects.get(id=settings.SITE_ID)
request.site = current_site
settings.SITE_ID = current_site.id
response = self.get_response(request)
return response
# settings.py
MIDDLEWARE = [
...
'library.middleware.DynamicSiteMiddleware',
]
7
中间件的代码格式好像发生了变化。现在这个版本(Django v3.1)的代码格式(看起来是可以用的):
from django.conf import settings
from django.contrib.sites.models import Site
class DynamicSiteDomainMiddleware:
def __init__(self, get_response):
self.get_response = get_response
# One-time configuration and initialization.
def __call__(self, request):
try:
current_site = Site.objects.get(domain=request.get_host())
except Site.DoesNotExist:
current_site = Site.objects.get(id=settings.DEFAULT_SITE_ID)
request.current_site = current_site
settings.SITE_ID = current_site.id
response = self.get_response(request)
return response
15
你可以创建一个自定义的中间件,它会读取请求并设置 SITE_ID。我在我的一个网站上使用了以下代码:
class SiteMiddleware(object):
def process_request(self, request):
try:
current_site = Site.objects.get(domain=request.get_host())
except Site.DoesNotExist:
current_site = Site.objects.get(id=settings.DEFAULT_SITE_ID)
request.current_site = current_site
settings.SITE_ID = current_site.id
你可以查看 Django 的文档,了解如何添加你自己的中间件。这里是链接:https://docs.djangoproject.com/en/dev/topics/http/middleware/