Адаптация MultiHostMiddleware для django 2.1+ - PullRequest
0 голосов
/ 05 февраля 2019

У меня есть один проект django с несколькими различными приложениями, которые должны быть размещены в разных доменах.Например, давайте назовем их:

Административный сайт, ourdashboard.com

Сайт первого контента oursite1.com

Сайт второго контента oursite2.com

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

Я запустил приложение под названием панель инструментов.Я хотел бы, чтобы это приложение размещалось на домене ourdashboard.com, где доступ к этому домену будет иметь прямой доступ к dashboard.urls.Поэтому я хочу разместить несколько сайтов в одном проекте django, где каждый домен будет связан с конкретным файлом URL приложения.

Я провел небольшое исследование и наткнулся на MultiHostMiddleware и попытался это осуществить.Выглядело просто и легко, но я никогда раньше не работал с промежуточным программным обеспечением djangos, и я ударил по кирпичной стене с самого начала.Я правильно реализовал код в соответствии с инструкциями, но продолжал получать 500 Internal Server Error.Сначала я думал, что что-то напутал в файле настроек, но не мог понять, в чем проблема.Затем я просмотрел логи и заметил, что класс промежуточного программного обеспечения не получает get_response.Немного больше исследований в Middleware Documentation показали мне, что инициализация и вызываемые функции требуются и что __init__ может получить только один аргумент 'get_response'.Кроме того, я узнал, что некоторые изменения в промежуточном программном обеспечении djangos произошли совсем недавно, а последнее обновление MultiHostMiddleware было сделано более 3 лет назад (в настоящее время я использую Django 2.1.5, поэтому изменения после промежуточного программного обеспечения).Я уже 6 часов смотрю на старый код в поисках возможного решения, но, честно говоря, я даже не знаю, с чего начать, когда дело доходит до промежуточного программного обеспечения.Я даже думал, что смогу применить существующие функции к требуемым, думая, что process_response - вызываемый объект, так как он возвращает ответ, но я просто упал в другую кроличью нору.Итак, я ищу способ адаптировать этот старый код для django 2.1 для размещения различных сайтов, используя один и тот же проект django.

settings.py

MIDDLEWARE = [
    'network.middleware.MultiHostMiddleware',
    ...
]

HOST_MIDDLEWARE_URLCONF_MAP = {
    "ourdahsboard.com": "dashboard.urls",
    "oursite1.com": "musiclounge.urls",
    "oursite2.com": "artworld.urls",
}

middleware.py

import time
from django.conf import settings
from django.utils.cache import patch_vary_headers

class MultiHostMiddleware:

    def process_request(self, request):
        try:
            request.META["LoadingStart"] = time.time()
            host = request.META["HTTP_HOST"]
            #if host[-3:] == ":80":
            #    host = host[:-3] # ignore default port number, if present

            # best way to do this.
            host_port = host.split(':')
            if len(host_port)==2:                    
                host = host_port[0] 

            if host in settings.HOST_MIDDLEWARE_URLCONF_MAP:
                request.urlconf = settings.HOST_MIDDLEWARE_URLCONF_MAP[host]
                request.META["MultiHost"] = str(request.urlconf)
            else:
                request.META["MultiHost"] = str(settings.ROOT_URLCONF)

        except KeyError:
            pass # use default urlconf (settings.ROOT_URLCONF)

    def process_response(self, request, response):
        if 'MultiHost' in request.META:
            response['MultiHost'] = request.META.get("MultiHost")

        if 'LoadingStart' in request.META:
            _loading_time = time.time() - int(request.META["LoadingStart"])
            response['LoadingTime'] = "%.2fs" % ( _loading_time, )

        if getattr(request, "urlconf", None):
            patch_vary_headers(response, ('Host',))
        return response

** ОБНОВЛЕНИЕ **

As, requestedstack error:

Traceback (most recent call last):
   File "/home/user/webapps/django_network/network/network/wsgi.py", line 16, in <module>
     application = get_wsgi_application()
   File "/home/user/webapps/django_network/lib/python3.7/Django-2.1.5-py3.7.egg/django/core/wsgi.py", line 13, in get_wsgi_application
     return WSGIHandler()
   File "/home/user/webapps/django_network/lib/python3.7/Django-2.1.5-py3.7.egg/django/core/handlers/wsgi.py", line 136, in __init__
     self.load_middleware()
   File "/home/user/webapps/django_network/lib/python3.7/Django-2.1.5-py3.7.egg/django/core/handlers/base.py", line 36, in load_middleware
     mw_instance = middleware(handler)
 TypeError: __init__() missing 1 required positional argument: 'get_response'

1 Ответ

0 голосов
/ 05 февраля 2019

Я думаю, что вы пишете в старом стиле MIDDLEWARE (существовавший до django 1.10), вам нужно обновить его так:

class MultiHostMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response


    def __call__(self, request):
        loading_time = time.time()
        request.META["LoadingStart"] = loading_time
        host = request.META["HTTP_HOST"]    
        host_port = host.split(':')
        response = self.get_response(request)
        if len(host_port)==2:                    
            host = host_port[0] 
        try:
            if host in settings.HOST_MIDDLEWARE_URLCONF_MAP:
                request.urlconf = settings.HOST_MIDDLEWARE_URLCONF_MAP[host]
                request.META["MultiHost"] = str(request.urlconf)
                response['MultiHost'] = str(request.urlconf)
            else:
                request.META["MultiHost"] = str(settings.ROOT_URLCONF)
                response["MultiHost"] = str(settings.ROOT_URLCONF)

        except KeyError:
            pass 
        _loading_time = time.time() - loading_time
        response['LoadingTime'] = "%.2fs" % ( _loading_time, )
        if getattr(request, "urlconf", None):
            patch_vary_headers(response, ('Host',)) 
        return response

FYI, это непроверенный код, ноэто предотвратит ошибку, с которой вы столкнулись в данный момент.

Обновление

Вы можете обновить промежуточное ПО django старого стиля до нового стиля в соответствии с этой документацией .Я думаю, что вы можете попробовать так:

from django.utils.deprecation import MiddlewareMixin

class MultiHostMiddleware(MiddlewareMixin):
    # rest of the code from your question
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...