我有一个Django应用程序(例如)example.com
。它包含许多子应用程序(比如)strength
,speed
和skill
。 URL方案类似于http://example.com/strength
,http://example.com/speed
和http://example.com/skill
。这就是我运行我的开发服务器的方式(使用runserver
)并且没有任何问题。
现在,在部署期间,我需要具有映射到这些子应用程序的子域。更具体地说,我希望http://x.example.com
映射到http://example.com/x
(对于x
的上述值),然后处理可以继续。
我google了一下,发现了两种方法。
request
对象中。然后我在我的应用程序逻辑中完成整个事情。 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
如何妥善解决这个问题?
答案 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)
我在我的服务器上测试了它,它似乎工作。