Django 1.11 如何从保存在 CMS 站点模型中的 HTML 中显示模板变量

Posted

技术标签:

【中文标题】Django 1.11 如何从保存在 CMS 站点模型中的 HTML 中显示模板变量【英文标题】:Django 1.11 How to display template variable from within HTML saved in model for CMS Site 【发布时间】:2018-01-25 10:03:27 【问题描述】:

在模板中,我需要从保存在模型实例中的 html 内容呈现 variable 。

以下是代码的精简部分。

page.html

% load static %
<html>
  <head>
    <styles, links, etc.>
    <title> object.title </title>
  </head>
  <body>
    <div> object.html_content </div>
  </body>
</html>

型号

class Page(models.Model):

  title = models.CharField(max_length=30)
  html_content = models.TextField()

GlobalMixin

# Used site wide for Global information.

class GlobalMixin(object):

  def get_context_data(self, *args, **kwargs):
    context = super(GlobalMixin, self).get_context_data(*args, **kwargs)
    context['variable'] = "A Global piece of information"
    return context 

查看

from .mixins import GlobalMixin
from .models import Page

PageView(GlobalMixin, generic.DetailView):

  model = Page
  template_name = "my_app/page.html"

  def get_context_data(self, *args, **kwargs):
    context = super(PageView, self).get_context_data(*args, **kwargs)
    return context

管理和 HTML 内容字段 然后我输入 admin,添加新页面,按照以下示例将我的 HTML 内容输入到 html_content 字段“Html Content”中。

<p>This is  variable  that I need to display within my rendered page!</p>

然后保存

浏览器结果

This is  variable  that I need to display within my loaded page!

我知道有 Django Flat Pages,但它看起来不适合我,因为我需要在我的模板中使用平面页面不提供的全局变量。

模板直接与模型内容一起呈现,无需查看它。 我想我需要处理视图中的 html_content 字段,然后将所需的上下文变量添加到返回的上下文中或保存一个临时模板文件,将 html_content 附加到文件中,然后渲染它。

我该怎么做? 是否有 Django 打包接口可用于在我的视图中处理模板?

【问题讨论】:

【参考方案1】:

我解决了。这是代码,如果其他人遇到此问题或有更好的方法,请分享。

将 View 类型更改为 TemplateView,在 url 中使用 slug 获取模型实例,使用 django.template.engines 将字符串转换为模板对象,然后渲染模板对象并在上下文中返回。

page.html

% load static %
<html>
  <head>
    <styles, links, etc.>
    <title> object.title </title>
  </head>
  <body>
    <!-- <div> object.html_content </div> -->
    <div> html_content </div>
  </body>
</html>

views.py

from django.views.generic.base import TemplateView
from .mixins import GlobalMixin
from .models import Page

# NEW
from django.shortcuts import get_object_or_404
from django.template import engines

PageView(GlobalMixin, TemplateView):  # generic.DetailView

  # model = Page
  template_name = "my_app/page.html"

  def get_context_data(self, *args, **kwargs):
    context = super(PageView, self).get_context_data(*args, **kwargs)

    # NEW
    context['object']  = get_object_or_404(Page, slug=self.kwargs['slug'])
    t = engines['django'].from_string(context['object'].html_content)
    context['html_content'] = t.render(context=context, request=None)
    return context

【讨论】:

【参考方案2】:

我认为您可以使用如下自定义过滤器。

文件路径

yourapp/templatetags/__init__.py yourapp/templatetags/filters.py

filters.py

from django import template
import re

register = template.Library()

@register.filter(name="change_global_variable")
def change_global_variable(value):
    return re.sub(r'\\(.*)\\', 'A global piece', value)

模板

% load static %
% load filters % //filters.py//
<html>
  <head>
    <styles, links, etc.>
    <title> object.title </title>
  </head>
  <body>
    <div> object.html_content | change_global_variable</div>
  </body>
</html>

【讨论】:

是的,这可行,但需要在我的应用程序中加载两次全局变量并增加处理时间。它会在视图 Mixin 中为模板中所需的所有其他字段加载 Globals 一次,然后再次通过过滤器处理模板。不过我喜欢你的想法。 那么,我宁愿用javascripts处理它。

以上是关于Django 1.11 如何从保存在 CMS 站点模型中的 HTML 中显示模板变量的主要内容,如果未能解决你的问题,请参考以下文章

Django CMS:如何避免在设置中设置 SITE_ID?

django cms 搜索多个站点?

Django CMS Apphook 不加载

如何在 Django 1.11 中运行 celery worker

Django-cms:“设置”对象没有属性“SITE_ID”

django-cms 和 jQuery