Кэширование Django для поддоменов

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

Теперь у меня включен кеш django по умолчанию для всех страниц для незарегистрированных пользователей. Мне пришлось неявно отключить кеш для пользовательских страниц, так как он обрабатывал эти страницы так же, как если бы они были страницами /, например. filmaster.com и michuk.filmaster.com — это одна и та же страница для django.

Знаете ли вы какой-нибудь хороший и простой способ заставить django понимать поддомены для кэширования? Или вы предлагаете мне просто явно кешировать каждое из представлений субдоменов?

Обновление: на самом деле рассмотрел этот решение, и это не совсем то, как мы это делаем. Мы не перенаправляем. Мы хотим, чтобы URL-адрес оставался в поддомене, поэтому мы просто вызываем представления непосредственно из промежуточного программного обеспечения.

Вы можете увидеть подробности хакерской реализации здесь: musielak.eu/public/film20/film20/core/middleware.py [Обновление: страница 404 не найдена] (пользователь: justookingaround, пароль:film@ ster -- да, мы с открытым исходным кодом). А вот jira для исправления хака: jira.filmaster.org/browse/FLM-54 (но это не совсем относится к проблеме — просто чтобы убедиться, что вы не думаете, что мы поддерживаем паршивое кодирование :P)


person michuk    schedule 21.04.2009    source источник


Ответы (2)


К сожалению, я не могу решить вашу основную проблему (кеширование поддоменов), кроме как сказать, что все, что я прочитал, подразумевает, что Django не может справиться с этим каким-либо элегантным способом. Возможно, это изменилось для версии 1.1, но если да, то я ничего об этом не встречал. В моем конкретном приложении я все равно не могу кэшировать субдомены, поэтому я не изучал, какие внутренние изменения могут потребоваться для улучшения этой работы.

Однако, что касается способа доступа к представлениям поддоменов, вы можете рассмотреть еще один вариант:

class SubdomainMiddleware:
    """
    Make the company specified by the subdomain available to views for
    appropriate processing.
    """
    def process_request(self, request):
        """
        Populate a company attribute on the request object with the company
        indicated by the requested subdomain.
        """
        domain_parts = request.get_host().split('.')

        if (len(domain_parts) > 2):
            subdomain = domain_parts[0]

            if (subdomain.lower() == 'www'):
                subdomain = ''
        else:
            subdomain = ''

        if subdomain != '':
            try:
                request.company = Company.objects.get(subdomain=subdomain)
            except Company.DoesNotExist:
                return HttpResponseRedirect(''.join(['http://test.com', reverse('findcompany')]))                
        else:
            request.company = None

Думаю, это говорит само за себя — это сильно измененная версия того, что я нашел на djangosnippets. Он просто анализирует поддомен, ищет его в таблице компаний, и, если это действительная компания, он добавляется к объекту запроса для обработки представлением. Таким образом, если оба test.com/test и sub.test.com/test действительны, представление может содержать эту логику, а не помещать ее в промежуточное программное обеспечение. Кроме того, мусорные поддомены легко передаются поисковому URL.

Я намеревался сравнить это с вашим промежуточным программным обеспечением (больше для моего собственного образования, чем для чего-либо еще), но URL-адрес, который вы указали для своего кода, возвращает 404.

person bouvard    schedule 01.07.2009
comment
URL-адрес находится под ssl: musielak.eu/public/film20/film20 - я не мог предоставить полные URL-адреса раньше из-за того, что вы новичок в StackOverflow :) Он использует очень похожую логику на ту, которую вы предоставили на самом деле, за исключением того, что после обнаружения поддомена происходит гораздо больше неприятных вещей. Нам определенно нужно переписать это дерьмо и применить правильный urls.py для субдоменов. Кстати, Filmaster — это проект с открытым исходным кодом, и вам (как и всем остальным) предлагается присоединиться. Вы можете прочитать больше на filmaster.org. - person michuk; 01.07.2009

Хорошо, вот исправление, которое мы действительно использовали. К сожалению, это требует взлома кода Django, в частности метода _generate_cache_header_key в django/trunk/django/utils/cache.py. Что мы делаем, так это просто проверяем, есть ли какой-либо поддомен в хосте HTTP, и если да, извлекаем из него поддомен и добавить его к ключу кеша. Мы также можем просто добавить хост, который будет работать почти так же, но будет занимать больше драгоценных битов в ОЗУ.

Вот jira: http://jira.filmaster.org/browse/FLM-84 А вот и использованный код. Используйте на свой риск!

def _generate_cache_header_key(key_prefix, request):
    """
       Returns a cache key for the header cache.
       With Filmaster hack for handling subdomain caching: http://jira.filmaster.org/browse/FLM-84
    """
    subdomain = None
    path = request.path

    # TODO: this is not a decent implementation, it will work only on domains with one dot it them
    # To fix it, we'd need to pass a param to the request object before CacheMiddleware
    # this current domain name in it, and use that domain name in the regexp below
    m = re.match(r"([^\.]+)\.[^\.]+\.[^\.]+", request.META['HTTP_HOST'])
    if m!=None:
        subdomain = m.group(1)

    if subdomain != None:
        path = subdomain + "___" + path
    path = md5_constructor(iri_to_uri(path))
    return 'views.decorators.cache.cache_header.%s.%s' % (key_prefix, path.hexdigest()) 
person michuk    schedule 01.09.2009