【问题标题】:Django 1.11 How to display template variable from within HTML saved in model for CMS SiteDjango 1.11 如何从保存在 CMS 站点模型中的 HTML 中显示模板变量
【发布时间】:2025-12-29 05:15:10
【问题描述】:

在模板中,我需要从保存在模型实例中的 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 打包接口可用于在我的视图中处理模板?

【问题讨论】:

    标签: html django templates views models


    【解决方案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处理它。