Django, субдомены и mod_rewrite.URL-адреса портятся при настройке развертывания - PullRequest
2 голосов
/ 11 августа 2010

У меня есть приложение на Django (скажем) example.com. Он содержит несколько подприложений (скажем) strength, speed и skill. Схема URL выглядит примерно так: http://example.com/strength, http://example.com/speed и http://example.com/skill. Вот так я запускаю свой dev-сервер (используя runserver), и никаких проблем не возникает.

Теперь, во время развертывания, мне нужно иметь субдомены, которые отображаются на эти субприложения. Более конкретно, я хочу, чтобы http://x.example.com отображался на http://example.com/x (для указанных выше значений x), и тогда обработка может продолжаться.

Я немного погуглил и нашел два способа сделать это.

  • Одним из них является получение некоторого промежуточного программного обеспечения для получения части субдомена URL-адреса и хранения его внутри объекта request, передаваемого моим методам просмотра. Затем я делаю все это в своей логике приложения.
  • Другой вариант - использовать Apache mod_rewrite, чтобы выполнить приведенный выше перевод URL, а затем запустить приложение как обычно.

Я выбрал последнее, так как оно выглядело аккуратнее, и я подумал, что мне не нужно будет включать специфичный для развертывания код в мое основное приложение.

Теперь меня укусила проблема, из которой я не могу найти выход. Внутри приложения skill у меня есть названный URL skill_home. Это http://example.com/skill. Однако после развертывания URL-адрес skill_home становится http://skill.example.com/skill. Django добавляет /skill к домену верхнего уровня, и это то, что я получаю. Если я сделаю GET для этого URL, 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 Ответ

3 голосов
/ 11 августа 2010

Для этого ответа я предполагаю, что вы готовы сделать 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)

Я проверил это на своем сервере, и похоже, что оно работает.

...