微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 Django CMS 中手动缓存 HTML 页面

如何解决在 Django CMS 中手动缓存 HTML 页面

我正在尝试为 Django CMS 构建一个插件,它将网站的静态副本保存在磁盘上。我已经设置了插件,并且我在工具栏上有一个按钮,可以触发一个浏览所有页面的视图,呈现它们并保存它们。

一般设置似乎工作正常,但是当我检查创建的静态 HTML 文件时,它们缺少每个页面插件内容

我的方法是重用 Django CMS 详细信息视图,该视图用于将页面呈现为对浏览器 HTTP 请求的响应。我怀疑该问题可能与传递给它的请求对象有关,因为我认为可用的请求实际上是管理页面请求,而不是我想要呈现的请求。但是我试图覆盖它的一些值,我还检查了 Django CMS GitHub 以查看请求是如何使用的,但我仍然无法显示插件内容

这是我的视图函数

from django.contrib.auth.models import AnonymousUser
from cms.views import details
from cms.models.pagemodel import Page

def create_html_files(request):
    cms_pages = Page.objects.filter(publication_date__isnull=False)
    request.user = AnonymousUser()
    done = []
    for page in cms_pages:
        languages = page.get_languages()
        for language in languages:
            url = page.get_public_url(language)
            if url not in done:
                slug = page.get_slug()
                done.append(url)
                path = get_path(url)  # Returns the path of the page
                request.path = path
                request.path_info = path
                request.current_page = page
                request.toolbar.show_toolbar = False
                if page.is_home:
                    template = details(request,'')
                else:
                    template = details(request,slug)
                content = ''
                if hasattr(template,'render'):
                    content = template.render().content
                else:
                    content = template.content

                content = content.decode("utf-8")

                with open(path,'w') as file:
                    file.write(content)

它会生成适当的文件,但没有内容。这是使用 Django CMS 正常呈现的页面。 IT 显示一些文本内容

A sample page rendered live with Django CMS.

这是使用我的视图生成的 HTML 页面。文本内容不存在,但呈现的页面“正确”(菜单突出显示了正确的页面)。

The same page rendered manually.

我已经尝试了所有我能想到的方法,但内容仍未显示。我希望有人有一个我没想到的简单修复方法

提前致谢!

编辑: 使用 admin 用户而不是 AnonymousUser(注释上面的行)确实呈现内容,但是:

  • 这没有任何意义。当我注销并查看实时站点时,我可以很好地看到内容。当我注销时,我使用的是 AnonymousUser,因此我需要使用 Admin 用户来呈现静态文件是没有意义的。
  • 出现在每个页面中的内容都是一样的,这意味着使用 Admin 用户只是给了我一些额外的权限,让我可以访问一些未发布的内容,但它不是当前页面内容。问题似乎在于确定要绘制的正确页面内容,而与用户无关。
  • 如果我使用管理员用户,我会在主菜单上看到不打算公开的页面(未发布的页面)。这绝对是不行的。

修改了当前虚拟环境中的原始 Django CMS 源代码,以记录在两种情况下传递给 details() 视图的请求对象的每个属性(当我尝试将它们呈现到静态文件时以及当我实时访问同一页面)。我比较了两个输出并发现了一些差异,但覆盖它们仍然无法显示内容

这是包含我试图覆盖的所有内容的新视图:

from django.contrib.auth.models import AnonymousUser
from cms.views import details
from cms.models.pagemodel import Page

def create_html_files(request):
    cms_pages = Page.objects.filter(publication_date__isnull=False)
    request.user = AnonymousUser()
    request._cached_user = request.user
    request._read_started = False
    # This one is very ugly,but in my desperation I simply copied the entire headers from the live request
    request.headers = {'Content-Length': '','Content-Type': 'text/plain','Host': 'localhost:8081','Connection': 'keep-alive','Cache-Control': 'max-age=0','Sec-Ch-Ua': '" Not;A Brand";v="99","Google Chrome";v="91","Chromium";v="91"','Sec-Ch-Ua-Mobile': '?0','Upgrade-Insecure-Requests': '1','User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/91.0.4472.77 Safari/537.36','Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9','sec-fetch-site': 'same-origin','sec-fetch-mode': 'navigate','Sec-Fetch-User': '?1','Sec-Fetch-Dest': 'document','Referer': 'http://localhost:8081/en/','Accept-Encoding': 'gzip,deflate,br','Accept-Language': 'en-US,en;q=0.9,ca;q=0.8,es;q=0.7','Cookie': 'django_language=en; _ga=GA1.1.1893957538.1621685583; sessionid_obres=ofe55t22ngs2b7m9xn4zoc2arop6ejlf; discovery=false; csrftoken=6ya4aflnaswZRvuCoSW2FALmBtgrrElxXfsbEf3TjMVgeX8xOMC6WjuNRvNWkXes'}
    del request.cms_latest_entry
    request.COOKIES.pop('sessionid')
    done = []
    for page in cms_pages:
        languages = page.get_languages()
        for language in languages:
            url = page.get_public_url(language)
            if url not in done:
                slug = page.get_slug()
                done.append(url)
                path = get_path(url)  # Returns the path of the page
                request.path = f"/{path}/"
                request.path_info = request.path
                request.Meta['PATH_INFO'] = request.path
                request.current_page = page
                request.toolbar.show_toolbar = False
                request._read_started = False
                if page.is_home:
                    template = details(request,'w') as file:
                    file.write(content)

我还检查了 the details() view 以尝试了解它如何使用请求对象,但我看不到任何可能产生此结果的内容

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。