ฉันมีโปรเจ็กต์ django โปรเจ็กต์เดียวที่มีแอปต่างๆ มากมายที่ควรโฮสต์บนโดเมนที่ต่างกัน ตัวอย่างเช่นลองเรียกพวกเขาว่า:
เว็บไซต์ผู้ดูแลระบบ ourdashboard.com
เว็บไซต์เนื้อหาแรก oursite1.com
เว็บไซต์เนื้อหาที่สอง oursite2.com
ไซต์แดชบอร์ดมีไว้สำหรับผู้เผยแพร่เนื้อหาเท่านั้น ในขณะที่ไซต์เนื้อหามีไว้สำหรับผู้เยี่ยมชม แต่ละไซต์มีความแตกต่างกันในแง่ของฟังก์ชันการทำงาน เนื้อหา และการออกแบบ ฉันต้องการให้ผู้เผยแพร่สามารถโพสต์เนื้อหาบนทั้งสองไซต์ได้ ดังนั้นฉันจะไม่สร้างโปรเจ็กต์ django ที่แตกต่างกัน แต่ประเภทของเนื้อหานั้นต้องการไซต์ที่แตกต่างกันสำหรับผู้ชมเฉพาะกลุ่ม
ฉันเริ่มแอปชื่อแดชบอร์ด ฉันต้องการให้แอปนี้โฮสต์บนโดเมน ourdashboard.com ซึ่งการเข้าถึงโดเมนนี้จะเข้าถึง dashboard.urls
โดยตรง โดยพื้นฐานแล้ว ฉันต้องการโฮสต์หลายไซต์โดยใช้โปรเจ็กต์ django เดียว โดยที่แต่ละโดเมนจะเชื่อมโยงกับไฟล์ URL ของแอปเฉพาะ
ฉันค้นคว้าข้อมูลเล็กน้อย และบังเอิญเจอ MultiHostMiddleware และพยายามนำไปใช้ ดูเรียบง่ายและใช้งานง่าย แต่เมื่อไม่เคยทำงานกับมิดเดิลแวร์ djangos มาก่อน ฉันจึงชนกำแพงตั้งแต่เริ่มต้น ฉันติดตั้งโค้ดอย่างถูกต้องตามคำแนะนำ แต่ฉันยังคงได้รับข้อผิดพลาดเซิร์ฟเวอร์ภายใน 500 ข้อ ตอนแรกฉันคิดว่าฉันทำบางอย่างผิดพลาดในไฟล์การตั้งค่าของฉัน แต่ไม่เห็นว่าปัญหาอยู่ที่ใด จากนั้น ฉันตรวจดูบันทึกและสังเกตเห็นว่าคลาสมิดเดิลแวร์ไม่ได้รับ get_response
การวิจัยเพิ่มเติมอีกเล็กน้อยใน เอกสารประกอบมิดเดิลแวร์ แสดงให้ฉันเห็นว่าจำเป็นต้องมีการเริ่มต้นและฟังก์ชันที่เรียกได้ และ __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",
}
มิดเดิลแวร์.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'