You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Wagtail开发:如何基于同一页面模型适配不同Bokeh图表模板

简化Wagtail+Bokeh页面结构的方案

1. 核心方案:单页面模型+可选择的Bokeh标签

给页面模型新增选择字段,让CMS后台编辑能直接选择要调用的Bokeh模板标签,再通过通用模板根据选择动态渲染内容,完全省去多模型多模板的冗余。

修改页面模型

from wagtail.models import Page
from django.db import models

class BokehPage(Page):
    # 保留原有文本字段,比如页面正文
    body = models.TextField()
    # 添加Bokeh标签选择器
    bokeh_tag = models.CharField(
        max_length=20,
        choices=[
            ('bokehgraph', 'Bokeh图表1'),
            ('bokehgraph2', 'Bokeh图表2'),
        ],
        default='bokehgraph',
        verbose_name='选择Bokeh图表类型'
    )

    content_panels = Page.content_panels + [
        models.FieldPanel('body'),
        models.FieldPanel('bokeh_tag'),
    ]

通用模板(bokeh_page.html)

模板中根据模型的选择值,加载对应的自定义标签:

{% extends "base.html" %}
{% load your_bokeh_tags %} <!-- 替换成你的自定义标签库名称 -->

{% block content %}
    <div class="page-content">
        {{ page.body|safe }}
        <div class="bokeh-wrapper">
            {% if page.bokeh_tag == 'bokehgraph' %}
                {% bokehgraph %}
            {% elif page.bokeh_tag == 'bokehgraph2' %}
                {% bokehgraph2 %}
            {% endif %}
        </div>
    </div>
{% endblock %}

后续新增Bokeh标签时,只需要给bokeh_tag的choices加选项,模板里补对应的判断即可,不用动模型和模板结构。

2. 进阶方案:用StreamField实现自由内容组合

如果需要更灵活的页面布局(比如文本和图表穿插、多图表组合),可以利用Wagtail的StreamField定义可复用的Bokeh组件:

定义StreamBlock

from wagtail.fields import StreamField
from wagtail.blocks import StructBlock, TextBlock, ChoiceBlock

class BokehGraphBlock(StructBlock):
    graph_type = ChoiceBlock(
        choices=[
            ('bokehgraph', '图表1'),
            ('bokehgraph2', '图表2'),
        ],
        required=True
    )

    class Meta:
        template = 'blocks/bokeh_graph_block.html'
        icon = 'graph'

class FlexibleBokehPage(Page):
    body = StreamField([
        ('text', TextBlock()),
        ('bokeh_graph', BokehGraphBlock()),
    ], use_json_field=True)

    content_panels = Page.content_panels + [
        models.FieldPanel('body'),
    ]

组件模板(blocks/bokeh_graph_block.html)

{% load your_bokeh_tags %}
<div class="bokeh-block">
    {% if self.graph_type == 'bokehgraph' %}
        {% bokehgraph %}
    {% elif self.graph_type == 'bokehgraph2' %}
        {% bokehgraph2 %}
    {% endif %}
</div>

这种方式让编辑能在页面里自由添加文本块和不同类型的Bokeh图表,完全不需要新增模型或模板,扩展性拉满。

3. 额外优化:模板标签参数化

如果Bokeh标签需要动态参数(比如不同数据源),可以给模型加参数字段,再在模板里传递给标签:

# 模型新增参数字段
bokeh_data_key = models.CharField(max_length=50, blank=True, verbose_name='数据源标识')

# 模板传递参数
{% if page.bokeh_tag == 'bokehgraph' %}
    {% bokehgraph page.bokeh_data_key %}
{% elif page.bokeh_tag == 'bokehgraph2' %}
    {% bokehgraph2 page.bokeh_data_key %}
{% endif %}

这样同一个标签能根据参数渲染不同内容,进一步减少重复代码。

内容的提问来源于stack exchange,提问作者John Moody

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 12:05:18