Промежуточное программное обеспечение хоста Django кэшируется - PullRequest
1 голос
/ 23 августа 2011

Я создал проект Django для управления двумя отдельными сайтами, которые имеют некоторый внутренний код.Оба сайта находятся внутри отдельных приложений.Каждое приложение имеет свои собственные models.py, views.py, шаблоны и т. Д. *

Чтобы иметь возможность по-разному реагировать на разные имена хостов, я создал промежуточное ПО URLconf:

class HostnameBasedUrlconfMiddleware(object):
    """This middleware parses the hostname from the request, and selects the
    urlconf accordingly.

    To set a custom urlconf according to the current hostname, add an URLCONF
    dictionary to your settings.py file.

    URLCONF = {
        'example.com': 'urls_example',
        'example.dev': 'urls_dev',
        'admin.example.dev': 'apps.admin.urls'
    }

    If the hostname is not found in the URLCONF dictionary, the default
    ROOT_URLCONF setting will be used.

    """

    def process_request(self, request):
        # Decide which urlconf to use. Fallback is to use the ROOT_URLCONF
        # as defined in the settings.py file.
        try:
            hostname = request.META['HTTP_HOST']
            request.urlconf = settings.URLCONF[hostname]
        except (KeyError, AttributeError):
            pass

        return None

Этосначала мне показалось, что он работает, но потом я осознал, что должно происходить какое-то кэширование.

При запуске сервера и запросе сайта A он будет отображаться.Если я запрашиваю сайт B, появляется сайт A.Иногда (но не всегда) после нескольких перезагрузок сайт B, наконец, появляется.После перезапуска сервера и запроса сайта B он будет отображаться, но теперь сайт A будет отображать содержимое сайта B.

Это произошло как со встроенным devserver, так и с gunicorn.

Я пыталсязапросить сайт с помощью curl, чтобы избежать кэширования в браузере, без разницы.

Я также подозревал, что это может быть своего рода коллизия имен шаблонов, но все шаблоны находятся внутри подпапки с уникальным именем в соответствующих папках шаблонов.

У меня не установлена ​​memcached, и я не использую промежуточное программное обеспечение для кэширования.

В чем может быть проблема?Есть ли какое-то внутреннее автоматическое кэширование?

1 Ответ

0 голосов
/ 23 августа 2011

Вот код, который подставляется в urlconf (по крайней мере, для 1.3):

django.core.handlers.base

class BaseHandler(object):

   [...snip...]

   def get_response(self, request):
        "Returns an HttpResponse object for the given HttpRequest"
        from django.core import exceptions, urlresolvers
        from django.conf import settings

        try:
            # Setup default url resolver for this thread, this code is outside
            # the try/except so we don't get a spurious "unbound local
            # variable" exception in the event an exception is raised before
            # resolver is set
            urlconf = settings.ROOT_URLCONF
            urlresolvers.set_urlconf(urlconf)
            resolver = urlresolvers.RegexURLResolver(r'^/', urlconf)
            try:
                response = None
                # Apply request middleware
                for middleware_method in self._request_middleware:
                    response = middleware_method(request)
                    if response:
                        break

                if response is None:
                    if hasattr(request, "urlconf"):
                        # Reset url resolver with a custom urlconf.
                        urlconf = request.urlconf
                        urlresolvers.set_urlconf(urlconf)
                        resolver = urlresolvers.RegexURLResolver(r'^/', urlconf)
    [...snip...]

Итак, похоже, что он просто использует значение непосредственно из request.urlconf. И ваше промежуточное ПО напрямую устанавливает значение request.

Я бы установил django-debug-toolbar , чтобы подтвердить, является или нет значение для request.urlconf а) устанавливаемым или б) изменяющимся в процессе.

Чтобы быть абсолютно уверенным, почему бы временно не изменить код на что-то вроде:

            request.urlconf = settings.URLCONF[hostname]
            request.urlconf_set = datetime.datetime.now()

Затем вы можете посмотреть значения на панели инструментов отладки (или просто вывести их в шаблон), чтобы увидеть, что может происходить.

Однако я бы предложил вместо использования промежуточного программного обеспечения просто настроить разные файлы settings.py для каждого домена. Затем на любом веб-сервере, который вы используете, настройте каждый из них на использование своего собственного файла .wsgi, который указывает на собственный файл настроек, например:

settings_a.py

from settings import *
ROOT_URLCONF = 'urls_a.py'

settings_b.py

from settings import *
ROOT_URLCONF = 'urls_b.py'
...