2013-05-12 15 views
2

我使用自定義中間件將子域映射到應用程序的urls.py,方法是將相關的urls.py分配給request.urlconf變量。Django - 網址模板標記與子域的分隔

這工作正常,除了{% url %}模板標記。
我得到一個NoReverseMatch,不知道爲什麼。
調試頁面顯示reverse函數收到參數view_name中的一個值,所以它應該可以工作。

發生這種情況{% url %}標籤在模板中。
如果我切換到類似文件夾的網址(例如myproject.com/sub,而不是sub.myproject.com),則標記正常工作。

關於爲什麼發生這種情況以及如何解決這個問題的任何想法都非常感謝。

+0

你可能想看看https://docs.djangoproject.com/en/1.5/ref/settings/#allowed-hosts - 沒有做到它..只是一個想法 – karthikr 2013-05-12 20:33:35

+0

@ karthikr,謝謝。我通讀了這個頁面,但沒有解決問題。 – user1102018 2013-05-12 20:44:03

回答

1

那麼,沒有找到我所需要的,我來到了以下解決方案。 我放棄了request.urlconf映射並進行了重寫request.path_info
我在這裏發佈我的解決方案,以防有人遇到這個問題。

第一步,下面的中間件添加到您的項目:

class SubdomainMiddleware: 
    """Subdomain for Django""" 
    def process_request(self, request): 
     domain_parts = request.get_host().lower().replace('www.', '').split('.example.com', 1) 
     if len(domain_parts) > 1 and domain_parts[0]: 
      subdomain = domain_parts[0] 
     else: 
      subdomain = None 

     if subdomain: 
      if request.path_info[-1] != '/': 
       request.path_info += '/' 
      request.path_info = '/%s%s' % (subdomain, request.path_info) 

接下來,添加以下代碼覆蓋reverse功能:

from django.conf import settings 
from django.core import urlresolvers 

_reverse = urlresolvers.reverse 

def reverse(*args, **kwargs): 
    # In case reversing a full url 
    if args[0].startswith('http'): 
     return args[0] 
    # In case reversing a url name 
    if '/' not in args[0]: 
     url = _reverse(*args, **kwargs) 
    else: 
     # In case reversing a url path 
     url = args[0] 

    parts = url.strip('/').split('/', 1) 
    subdomain = parts[0] 
    path = parts[1] if len(parts) > 1 else '' 
    protocol = 'http://' if settings.DEBUG else 'https://' 
    return '%s%s%s/%s' % (protocol, subdomain, '.example.com', path) 

urlresolvers.reverse = reverse 

我把它放在同一個文件自定義中間件坐。

就是這樣!

據我瞭解和測試,一切正常:倒車時,重定向,模板{%URL%}標籤等

注:
我做了這個代碼的三個假設:

  • 域名是example.com。根據需要更改它,將它放在settings.py之內,無論適合你。
  • 子域映射到子文件夾。例如。 sub.example.com將被轉換爲example.com/sub
  • 我的網站在任何地方都使用SSL。因此,我只需檢查自定義reverse函數中的值settings.DEBUG以查看它是否應使用httphttps

希望它有幫助。