Django: 如何根据URL动态设置settings.py中的SITE_ID?

7 投票
3 回答
3857 浏览
提问于 2025-04-30 16:31

有什么好的方法可以根据网址中的域名动态设置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/

撰写回答