Django 在Apache中,如何将一个目录别名到文件系统,并将其子目录别名到WSGI文件?

Django 在Apache中,如何将一个目录别名到文件系统,并将其子目录别名到WSGI文件?,django,apache,apache-config,Django,Apache,Apache Config,我使用nginx作为apache/mod_wsgi和Django的反向代理。目前,使用/aliasing my wsgi文件和/media aliasing my media目录时,一切正常。但是,我想对它进行设置,以便/media/foo/bar还可以为我的wsgi文件添加别名,这样/media/foo/example.txt将在apache中提供example.txt,但是/media/foo/bar/example.txt将被传递到Django中的我的url.py 我已经尝试在/media

我使用nginx作为apache/mod_wsgi和Django的反向代理。目前,使用/aliasing my wsgi文件和/media aliasing my media目录时,一切正常。但是,我想对它进行设置,以便/media/foo/bar还可以为我的wsgi文件添加别名,这样/media/foo/example.txt将在apache中提供example.txt,但是/media/foo/bar/example.txt将被传递到Django中的我的url.py

我已经尝试在/media/别名上方的apache.conf中添加另一个WSGIScriptAlias,但是/media/foo/bar/example.txt仍然由apache提供服务。我的apache.conf当前如下所示:

<VirtualHost *:8080>
    #DocumentRoot /var/www/mydomain.com/public
    ServerName mydomain.com
    ErrorLog /var/www/mydomain.com/logs/apache_error_log
    CustomLog /var/www/mydomain.com/logs/apache_access_log common

    WSGIScriptAlias /media/foo/bar /var/www/mydomain.com/src/myproject/server/django.wsgi
    Alias /media/ /var/www/mydomain.com/public/media/
    <Directory /var/www/mydomain.com/public/media>
        Order deny,allow
        Allow from all
    </Directory>

    WSGIScriptAlias / /var/www/mydomain.com/src/myproject/server/django.wsgi

    <Directory /var/www/mydomain.com/src/myproject/server>
        Order allow,deny
        Allow from all
    </Directory>
</VirtualHost>

最快的方法是在Apache配置中将mod_wsgi移到mod_alias之前,但这实际上会导致由Django应用程序处理/media

如果AliasMatch支持lookahead regexp,您应该能够执行以下操作:

别名匹配/媒体/?!福


这应该可以避免这个问题——也就是说,我倾向于推荐从另一个主机名media.example.org提供媒体服务,因为这会由于并行性而获得一些很好的客户端性能优势,并简化服务器优化问题。

快速解决方法是在Apache配置中将mod_wsgi移到mod_alias之前,但这实际上会导致您的Django应用程序处理/media

如果AliasMatch支持lookahead regexp,您应该能够执行以下操作:

别名匹配/媒体/?!福


这应该可以避免这个问题——也就是说,我倾向于推荐从另一个主机名media.example.org提供介质,因为这样可以通过并行性获得一些不错的客户端性能优势,并简化服务器优化问题。

因为Alias和WSGIScriptAlias处于不同的优先级,您不能创建两个以上级别的多级别重叠URL集,这些URL在使用它们之间交替。解决方案是对所有子URL使用Alias/AliasMatch指令,以相同的优先级对它们进行评估。仍然可以将WSGIScriptAlias用作站点的根目录

因此,尝试使用以下with指令,以便使大多数嵌套URL模式早于外部URL

<VirtualHost *:8080>
#DocumentRoot /var/www/mydomain.com/public
ServerName mydomain.com
ErrorLog /var/www/mydomain.com/logs/apache_error_log
CustomLog /var/www/mydomain.com/logs/apache_access_log common

AliasMatch ^/(media/foo/bar/.*) /var/www/mydomain.com/src/myproject/server/django.wsgi/$1
Alias /media/ /var/www/mydomain.com/public/media/
WSGIScriptAlias / /var/www/mydomain.com/src/myproject/server/django.wsgi

<Directory /var/www/mydomain.com/src/myproject/server>
    Options ExecCGI
    AddHandler wsgi-script .wsgi
    # WSGIApplicationGroup %{GLOBAL}
    Order allow,deny
    Allow from all
</Directory>

<Directory /var/www/mydomain.com/public/media>
    Order deny,allow
    Allow from all
</Directory>
</VirtualHost>
AliasMatch用于最嵌套的应用程序,因为我们需要调整Django应用程序看到的SCRIPT_NAME的值,即mount point,这样请求似乎仍然是针对安装在根目录下的Django实例的。如果不这样做,URL.py模式将不会像您期望的那样为该子URL工作。使用AliasMatch并在脚本路径之后使用$1将匹配的子模式添加到RHS可以实现这一点


尽管Django是通过两个不同的指令装载的,但计算出的脚本_名称对于这两个指令应该是相同的,因此应该使用相同的Python子解释器。如果出于某种原因,您认为自己的内存使用量是预期的两倍,即在不同的子解释器中运行两个Django实例,则可以通过取消上面的WSGIApplicationGroup指令的注释来强制它们在相同的子解释器中运行。但这不应该是必需的,如果您认为确实需要它,最好转到mod_wsgi邮件列表,并可以指导您如何验证是否应该这样做以及错误是什么。

因为Alias和WSGIScriptAlias处于不同的优先级,您不能创建两个以上级别的多级别重叠URL集,这些URL在使用它们之间交替。解决方案是对所有子URL使用Alias/AliasMatch指令,以相同的优先级对它们进行评估。仍然可以将WSGIScriptAlias用作站点的根目录

因此,尝试使用以下with指令,以便使大多数嵌套URL模式早于外部URL

<VirtualHost *:8080>
#DocumentRoot /var/www/mydomain.com/public
ServerName mydomain.com
ErrorLog /var/www/mydomain.com/logs/apache_error_log
CustomLog /var/www/mydomain.com/logs/apache_access_log common

AliasMatch ^/(media/foo/bar/.*) /var/www/mydomain.com/src/myproject/server/django.wsgi/$1
Alias /media/ /var/www/mydomain.com/public/media/
WSGIScriptAlias / /var/www/mydomain.com/src/myproject/server/django.wsgi

<Directory /var/www/mydomain.com/src/myproject/server>
    Options ExecCGI
    AddHandler wsgi-script .wsgi
    # WSGIApplicationGroup %{GLOBAL}
    Order allow,deny
    Allow from all
</Directory>

<Directory /var/www/mydomain.com/public/media>
    Order deny,allow
    Allow from all
</Directory>
</VirtualHost>
AliasMatch用于最嵌套的应用程序,因为我们需要调整Django应用程序看到的SCRIPT_NAME的值,即mount point,这样请求似乎仍然是针对安装在根目录下的Django实例的。如果不这样做,URL.py模式将不会像您期望的那样为该子URL工作。使用AliasMatch并在脚本路径之后使用$1将匹配的子模式添加到RHS可以实现这一点


尽管Django是通过两个不同的指令装载的,但计算出的脚本_名称对于这两个指令应该是相同的,因此应该使用相同的Python子解释器。如果出于某种原因,您认为自己的内存使用量是预期的两倍,即在不同的子解释器中运行两个Django实例,则可以通过取消上面的WSGIApplicationGroup指令的注释来强制它们在相同的子解释器中运行。不过,这不应该是必需的,如果您认为确实需要它,最好转到mod_wsgi邮件列表,并可以指导您如何验证是否应该这样做以及错误是什么。

在使用Apache 2.X时,在Apache配置中更改mod_alias和mod_wsgi的LoadModule行顺序不会有任何区别。更改Alias和WSGIScriptAlias指令的顺序也不起作用。这是因为mod_wsgi总是遵从mod_alias指令,而不管顺序如何。是o
仅在Apache1.3中,顺序在LoadModule行中很重要,这是因为Apache1.3没有一种方法让模块在内部定义相对于其他模块的优先顺序。结果表明,先行否定实际上不起作用。它无法匹配/media/foo,但是它也无法匹配任何其他内容。。。仍在寻找一个可行的解决方案。在使用Apache2.X时,更改Apache配置中mod_alias和mod_wsgi的LoadModule行的顺序不会有任何区别。更改Alias和WSGIScriptAlias指令的顺序也不起作用。这是因为mod_wsgi总是遵从mod_alias指令,而不管顺序如何。只有在Apache1.3中,顺序在LoadModule行中才起作用,这是因为Apache1.3没有一种方法让模块在内部定义相对于其他模块的优先顺序。它无法匹配/media/foo,但是它也无法匹配任何其他内容。。。仍然在寻找一个可行的解决方案。好的,这是有效的!我确实需要做一个更改,但是,我只需要在别名上添加一个尾随斜杠,如下所示:Alias//var/www/mydomain.com/src/myproject/server/django.wsgi/否则它将尝试转到/var/www/mydomain.com/src/myproject/django.wsgifavicon.ico并失败。奇怪,对于站点的根目录,别名和ScriptAlias的行为彼此不同,对于WSGIScriptAlias也不同。我可能能够修复mod_wsgi来处理ScriptAlias用于站点根目录但映射到mod_wsgi的位置,但如果使用了Alias,则甚至不会到达mod_wsgi,除非如您所指出的那样添加了尾部斜杠。无论如何,我已经更改了示例,将WSGIScriptAlias用于站点的根目录,而仅将Alias指令用于子URL。这样就可以在不需要添加尾随斜杠的情况下工作了。好吧,这就行了!我确实需要做一个更改,但是,我只需要在别名上添加一个尾随斜杠,如下所示:Alias//var/www/mydomain.com/src/myproject/server/django.wsgi/否则它将尝试转到/var/www/mydomain.com/src/myproject/django.wsgifavicon.ico并失败。奇怪,对于站点的根目录,别名和ScriptAlias的行为彼此不同,对于WSGIScriptAlias也不同。我可能能够修复mod_wsgi来处理ScriptAlias用于站点根目录但映射到mod_wsgi的位置,但如果使用了Alias,则甚至不会到达mod_wsgi,除非如您所指出的那样添加了尾部斜杠。无论如何,我已经更改了示例,将WSGIScriptAlias用于站点的根目录,而仅将Alias指令用于子URL。这样就不需要添加尾部斜杠了。