2009-04-21 68 views
2

我使用子域在Django用戶頁面通過中間件以類似的方式,以所描述的內容hereDjango的緩存子域

現在,我有Django缺省高速緩存開啓沒有登錄的用戶的所有頁面。我必須爲用戶頁面隱式禁用緩存,因爲它像處理/頁面一樣處理這些頁面,例如, filmaster.com和michuk.filmaster.com是django的同一頁面。

你知道有什麼好的和簡單的方法來強迫django瞭解緩存的子域嗎?或者你建議我只是明確緩存每個子域視圖?

更新:實際上調查solution,這不完全是我們如何做到的。我們不重定向。我們希望URL保留在子域中,所以我們只是直接從中間件調用視圖。

你可以在這裏看到哈克實現的細節:musielak.eu/public/film20/film20/core/middleware.py [更新:404頁未找到(用戶:justlookingaround,道:電影@ STER - 是的,我們是開源的)。這裏有一個解決黑客攻擊的jira:jira.filmaster.org/browse/FLM-54(但這與問題並不完全相關 - 只是爲了確保您不認爲我們支持蹩腳的編碼:P)

回答

0

OK,這裏是我們實際使用的修復。不幸的是,它涉及到攻擊Django代碼,特別是django/trunk/django/utils/cache.py中的_generate_cache_header_key方法 我們所做的只是檢查HTTP主機中是否存在任何子域,如果是,則從中提取子域並將其追加到緩存鍵。 我們也可以簡單地附加主機,這將工作非常相似,但在RAM中採取一些更寶貴的位。

這裏是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()) 
0

不幸的是,我無法解決您的主要問題(緩存子域),只能說我讀過的所有內容都暗示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返回一個404

+0

該URL位於ssl:https:// musielak下。eu/public/film20/film20 - 由於在StackOverflow中成爲新手,我無法提供完整的網址:) 它使用與您實際提供的邏輯非常類似的邏輯,除了有更多令人討厭的事情發生之後檢測子域。我們肯定需要重寫那些廢話併爲子域名應用一些適當的urls.py。 順便說一句,Filmaster是一個開源項目,你(和其他人一樣)被邀請加入。你可以在http://filmaster.org上閱讀更多內容 – michuk 2009-07-01 16:28:04