【问题标题】:Django caching for subdomains子域的 Django 缓存
【发布时间】:2015-05-25 21:24:33
【问题描述】:

我在 django 中通过 middleware hacksubdomains 用于用户页面,其方式与 here 中描述的类似:

现在,我为未登录用户的所有页面打开了默认的 django 缓存。我必须为用户页面隐式禁用缓存,因为它将这些页面视为 / 页面,例如filmaster.com 和 michuk.filmaster.com 与 django 是同一页面。

您知道强制 django 理解子域以进行缓存的任何好方法吗?还是您建议我明确地缓存每个子域视图?

更新:实际上调查了solution,但这并不是我们的做法。我们不重定向。我们希望 url 保留在子域中,所以我们所做的只是直接从中间件调用视图。

您可以在此处查看 hacky 实现的详细信息:musielak.eu/public/film20/film20/core/middleware.py [Update:404 page not found](用户:justlookingaround, pass :film@ster -- 是的,我们是开源的)。这是一个修复黑客的jira:jira.filmmaster.org/browse/FLM-54(但这与问题并不完全相关 - 只是为了确保您不认为我们支持蹩脚的编码:P)

【问题讨论】:

    标签: django caching subdomain


    【解决方案1】:

    不幸的是,我无法解决您的主要问题(缓存子域),只是说我所阅读的所有内容都暗示 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。

    我原本打算将此与您的中间件进行比较(更多的是为了我自己的教育而不是其他任何东西),但是您为代码提供的 URL 返回 404。

    【讨论】:

    • 网址在 ssl 下:musielak.eu/public/film20/film20 - 由于是 StackOverflow 的新手,我之前无法提供完整的网址 :) 它使用的逻辑与您实际提供的逻辑非常相似,除了那个检测到子域后会发生更多令人讨厌的事情。我们肯定需要重写那些废话并为子域应用一些适当的 urls.py。顺便说一句,Filmaster 是一个开源项目,邀请您(和其他所有人一样)加入。你可以阅读更多filmaster.org
    【解决方案2】:

    好的,这是我们实际使用的修复程序。不幸的是,它确实涉及破解 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()) 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-01
      • 2013-10-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多