Django,子域名和mod_rewrite。网站搞砸了部署设置

时间:2010-08-11 18:55:58

标签: python django mod-rewrite subdomain

我有一个Django应用程序(例如)example.com。它包含许多子应用程序(比如)strengthspeedskill。 URL方案类似于http://example.com/strengthhttp://example.com/speedhttp://example.com/skill。这就是我运行我的开发服务器的方式(使用runserver)并且没有任何问题。

现在,在部署期间,我需要具有映射到这些子应用程序的子域。更具体地说,我希望http://x.example.com映射到http://example.com/x(对于x的上述值),然后处理可以继续。

我google了一下,发现了两种方法。

  • 一个是获取一些中间件来获取URL的子域部分并将其保存在传递给我的视图方法的request对象中。然后我在我的应用程序逻辑中完成整个事情。
  • 另一种方法是使用Apache mod_rewrite进行上述URL转换,然后让我的应用程序像往常一样运行。

我之所以选择后者,因为它看起来更整洁,我认为我不必在核心应用程序中包含特定于部署的代码。

现在,我被一个我无法找到出路的问题所困扰。在skill应用程序中,我有一个名为url skill_home。它是http://example.com/skill。但是,部署后,skill_home网址会变为http://skill.example.com/skill。 Django将/skill附加到顶级域名,这就是我得到的。如果我对此网址进行了GET操作,则mod_rewrite会将其更改为http://skill.example.com/skill/skill,但不起作用。

我的mod_rewrite代码段看起来像这样

RewriteCond %{HTTP_HOST} !www.example.com$ [NC]
RewriteCond %{HTTP_HOST} ^(www.)?skill.example.com [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*) /skill/$1 

如何妥善解决这个问题?

1 个答案:

答案 0 :(得分:3)

对于这个答案,我假设你愿意为每个子域做mod_rewrite。我认为这不适用于任何子域(即您提到的x)。

这将删除前导/skill/,以便您的应用继续发挥作用:

RewriteCond %{HTTP_HOST} !www.example.com$ [NC]
RewriteCond %{HTTP_HOST} ^(www.)?skill.example.com [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (/skill/)?(.*) /skill/$2

更新

好的,所以你想在链接本身中删除URL的前导部分。

基本上,这意味着您必须编写自定义标记来替换{%url%}标记,如下所示:

import re
from django.template import Library
from django.template.defaulttags import URLNode, url

register = Library()

class SubdomainURLNode(URLNode):
    def render(self, context):
        domain = context['request'].get_host()
        subdomain = re.sub(r'^www\.','',domain).split('.')[0]
        path = super(SubdomainURLNode, self).render(context)
        return re.sub(r'^/%s/' % subdomain, '/', path)

@register.tag
def subdomainurl(parser, token, node_cls=SubdomainURLNode):
    """Just like {% url %} but checks for a subdomain."""
    node_instance = url(parser, token)
    return node_cls(view_name=node_instance.view_name,
        args=node_instance.args,
        kwargs=node_instance.kwargs,
        asvar=node_instance.asvar)

我在我的服务器上测试了它,它似乎工作。