Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在Django中基于服务器名称动态服务静态内容_Python_Django - Fatal编程技术网

Python 在Django中基于服务器名称动态服务静态内容

Python 在Django中基于服务器名称动态服务静态内容,python,django,Python,Django,我正在用Django编写一个web应用程序,可以从多个域访问同一IP地址。其理念是,应用程序访问的每个域都将获得独特的品牌 因此,例如,如果有两个域,reseller.com和oem.com,并且您访问了oem.com,它会将您带到与reseller.com相同的网站,但主题不同(例如,从/static/oem.com/{files}而不是/static/reseller.com/{files}发送) 基本上,我的想法是定义一个自定义模板标记,该标记接收服务器名称作为参数,该参数将返回内容的位置

我正在用Django编写一个web应用程序,可以从多个域访问同一IP地址。其理念是,应用程序访问的每个域都将获得独特的品牌

因此,例如,如果有两个域,reseller.com和oem.com,并且您访问了oem.com,它会将您带到与reseller.com相同的网站,但主题不同(例如,从/static/oem.com/{files}而不是/static/reseller.com/{files}发送)

基本上,我的想法是定义一个自定义模板标记,该标记接收服务器名称作为参数,该参数将返回内容的位置

有没有其他选择,或者只是更简单的选择

编辑:我应该补充一点,我正在使用MongoDB进行这个项目,因此Django的ORM很可能不会用于这个项目


再次编辑:更多澄清;我正在使用nginx。

您正在寻找。

例如,Apache有mod_rewrite,您可以使用它来重写URL:

重写COND%{HTTP_REFERER}^www.domain1.com$[NC]
重写规则/static/[^/]+/static/domain1/$1[L]
RewriteCond%{HTTP_REFERER}^www.domain2.com$[NC]
重写规则/static/[^/]+/static/domain2/$1[L]
(这是未经测试的)

其他服务器也有类似的功能


只需确保django应用程序发出的静态URL与站点无关,并且可以正确重写。

不确定如何在nginx中执行简单的重写规则。除了模板标签(如果你只交换静态内容,那么我认为模板标签是最好的选择),如果网站在模板方面会有所不同,你可以通过编写自定义模板加载器来处理它

这允许您选择在呈现页面时要使用的模板。如果加载程序无法为特定域找到匹配的模板,则此方法会以一种优雅的方式失败。如果找不到匹配项,它将返回到主模板目录。因此,您可以为某些域定制内容,而为其他域定制更通用的内容

但是,要根据请求头决定服务什么,您需要通过_thread_locals将请求提供给加载器,我在一些中间件中这样做:

#custom.middleware.py
try:
    from threading import local
except ImportError:
    from django.utils._threading_local import local

_thread_locals = local()

def get_current_request():
    return getattr(_thread_locals, 'request', None)

class RequestMiddleware():
    def process_request(self, request):
        _thread_locals.request = request
#custom.loaders.py
from os.path import join
from django.conf import settings
from django.template import TemplateDoesNotExist
from path.to.middleware import get_current_request

def load_template_source(template_name, template_dirs=None):
    request = get_current_request()
    host = request.get_host()
    path_to_template_dir = None
    for site in settings.SITE_TEMPLATE_FOLDERS:
        if site[0] == host:
            path_to_template_dir = site[1]
            break

    if path_to_template_dir:
        try:
            filepath = join(path_to_template_dir, template_name)
            file = open(filepath)
            try:
                return (file.read(), filepath)
            finally:
                file.close()
        except IOError:
                pass

    raise TemplateDoesNotExist(template_name)
接下来编写模板加载器(更新中间件的路径):

最后,用三件事更新您的设置文件1)添加模板加载器(确保首先列出模板加载器)2)添加中间件3)然后添加一个新的变量SITE_template_FOLDERS,其中包含一个元组,元组包含域和模板文件夹路径:

#settings.py

.....

TEMPLATE_LOADERS = (
    'custom.loaders.load_template_source',
    'django.template.loaders.filesystem.load_template_source',
    'django.template.loaders.app_directories.load_template_source',
)

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'domain.middleware.SessionMiddleware',
    'custom.middleware.RequestMiddleware',
)

SITE_TEMPLATE_FOLDERS = (
    ('mydomain.com', '/path/to/templates'),
    ('myotherdomain.com', '/path/to/other/templates')
)
...

看起来很多,但现在您可以通过设置文件轻松添加一个新域。

您能基于Referer HTTP头重写静态URL吗?您能详细说明一下吗?我已经检查了request.META的基本url,当然没有设置HTTP_REFERER。谢谢你的Ignacio,但我很可能不会使用Django的ORM,因为我在项目中使用MongoDB。不过,我会保留我的答案,因为其他搜索者可能可以使用它。@Nathan Hoad:你可以在网站上使用Django ORM,会话和身份验证,并且仍然使用MongoDB进行其他工作。这看起来很棒。我会调查一下,让你知道。这太棒了!我采用了一种非常简单的方法,使用~20行的上下文管理器,但我将与我的团队的其他成员讨论这种方法。但是,当静态内容由单独的专用服务器提供时,这没有帮助。这是一种不同于原问题中提出的解决方案,但它提供了一些额外的渲染灵活性。就像我前面说的,如果你纯粹想交换静态内容,那么这不是一个好办法。
#settings.py

.....

TEMPLATE_LOADERS = (
    'custom.loaders.load_template_source',
    'django.template.loaders.filesystem.load_template_source',
    'django.template.loaders.app_directories.load_template_source',
)

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'domain.middleware.SessionMiddleware',
    'custom.middleware.RequestMiddleware',
)

SITE_TEMPLATE_FOLDERS = (
    ('mydomain.com', '/path/to/templates'),
    ('myotherdomain.com', '/path/to/other/templates')
)
...