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

如何在Wagtail API富文本响应中将embed元素替换为img元素?

解决Wagtail API富文本图片返回<embed>而非<img>的问题

方案1:自定义RichText序列化器

通过重写Wagtail API的富文本序列化器,自动替换响应中的<embed>标签为带图片源的<img>标签。

步骤1:创建自定义序列化器

在你的应用目录下新建serializers.py,写入以下代码:

from wagtail.api.v2.serializers import RichTextSerializer
from wagtail.images.models import Image
import re

class CustomRichTextSerializer(RichTextSerializer):
    def to_representation(self, value):
        # 获取原始富文本HTML
        html = super().to_representation(value)
        
        # 匹配图片类型的embed标签
        embed_pattern = re.compile(r'<embed alt="([^"]+)" embedtype="image" format="([^"]+)" id="(\d+)"/>')
        
        def replace_embed(match):
            alt_text = match.group(1)
            image_format = match.group(2)
            image_id = match.group(3)
            
            try:
                # 根据ID获取图片实例
                image = Image.objects.get(id=image_id)
                # 获取对应格式的图片渲染版本(需和Wagtail后台配置的图片格式匹配)
                rendition = image.get_rendition(f'fill-{image_format}')
                # 返回替换后的img标签
                return f'<img src="{rendition.url}" alt="{alt_text}" class="{image_format}"/>'
            except Image.DoesNotExist:
                # 图片不存在时返回原标签,避免API报错
                return match.group(0)
        
        # 替换所有匹配的embed标签
        modified_html = embed_pattern.sub(replace_embed, html)
        return modified_html

步骤2:注册自定义API视图集

在项目的API路由配置文件(如api.py)中,替换默认的Pages视图集,指定自定义序列化器:

from wagtail.api.v2.views import PagesAPIViewSet
from wagtail.api.v2.router import WagtailAPIRouter
from .serializers import CustomRichTextSerializer

api_router = WagtailAPIRouter('wagtailapi')

class CustomPagesAPIViewSet(PagesAPIViewSet):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 为body字段绑定自定义序列化器
        self.serializer_class._declared_fields['body'] = CustomRichTextSerializer()

api_router.register_endpoint('pages', CustomPagesAPIViewSet)

方案2:在页面模型中添加处理后的字段

如果不想修改全局API序列化器,可以在页面模型中新增一个处理后的字段,专门返回替换完成的富文本内容。

代码示例

from wagtail.models import Page
from wagtail.fields import StreamField
from wagtail.api import APIField
import re
from wagtail.images.models import Image

class YourPageModel(Page):
    body = StreamField(...)  # 你的原始富文本字段
    
    # 定义API返回的字段,替换原body为处理后的版本
    api_fields = [
        APIField('processed_body'),
        # 其他需要返回的字段...
    ]
    
    @property
    def processed_body(self):
        processed_blocks = []
        for block in self.body:
            if block.block_type == 'rich_text':
                html = block.value
                # 匹配并替换embed标签,逻辑和方案1一致
                embed_pattern = re.compile(r'<embed alt="([^"]+)" embedtype="image" format="([^"]+)" id="(\d+)"/>')
                
                def replace_embed(match):
                    alt_text = match.group(1)
                    image_format = match.group(2)
                    image_id = match.group(3)
                    try:
                        image = Image.objects.get(id=image_id)
                        rendition = image.get_rendition(f'fill-{image_format}')
                        return f'<img src="{rendition.url}" alt="{alt_text}" class="{image_format}"/>'
                    except Image.DoesNotExist:
                        return match.group(0)
                
                modified_html = embed_pattern.sub(replace_embed, html)
                processed_blocks.append({
                    'type': 'rich_text',
                    'value': modified_html
                })
            else:
                # 非富文本块直接保留原始数据
                processed_blocks.append(block.serialized_data)
        return processed_blocks

注意事项

  • 图片渲染格式(如fill-{image_format})需要和你在Wagtail后台配置的图片格式名称对应,比如后台定义的fullwidth格式对应fill-1200x600,需要根据实际情况调整。
  • 务必处理Image.DoesNotExist异常,防止因图片被删除导致API请求失败。

内容的提问来源于stack exchange,提问作者Daniel Erazo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 04:30:17