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

在Django模板中能否从富文本内容提取图片作为海报?

实现方案:从CKEditor内容提取首图作为海报

这个需求完全可以实现,更推荐在模型层或自定义模板过滤器中处理HTML解析,而非直接在模板里硬写逻辑(不符合Django的职责划分,也容易出错),下面给出两种可行方案:

方案一:给List模型添加方法(最直观)

步骤1:安装HTML解析库

首先安装beautifulsoup4,用来安全解析CKEditor生成的HTML内容:

pip install beautifulsoup4

步骤2:修改List模型

在模型中新增一个方法,专门提取内容里的第一张图片链接:

from bs4 import BeautifulSoup
from django.db import models
from django.contrib.auth.models import User
from django.utils.text import slugify

class List(models.Model):
    title = models.CharField(max_length=120)
    genre = models.ManyToManyField('Genre')
    creator = models.ForeignKey(User,on_delete=models.SET_NULL,blank=True, null=True)
    posted = models.DateTimeField(auto_now_add=True)
    content = RichTextField(null=True,default=' ')
    type = models.CharField(max_length=10,default="Movie")
    spoiler_choices = [(False, 'No'),(True, 'Yes')]
    spoiler = models.BooleanField(default=False,null=True, choices = spoiler_choices)
    slug = models.SlugField(max_length= 300,null=True, blank = True, unique=True)

    def __str__(self):
        return f'{self.title}|{self.creator}'
    
    def save(self, *args, **kwargs):
        self.slug = slugify(self.title + str(self.posted))
        super(List,self).save(*args, **kwargs)
    
    # 新增方法:提取第一张图片的src
    def get_first_image_src(self):
        if not self.content:
            return None
        # 解析HTML内容
        soup = BeautifulSoup(self.content, 'html.parser')
        first_img = soup.find('img')
        # 返回图片链接,没有则返回None
        return first_img['src'] if first_img else None

步骤3:修改模板代码

在遍历query时,直接调用模型方法判断并替换图片:

{% for film in query %}
      <div class="elements">
        <div class="thumb">
          <img src="{% if film.get_first_image_src %}{{ film.get_first_image_src }}{% else %}{% static 'app/images/movie-poster.jpg' %}{% endif %}" width="100px" />
        </div>
        {% if film.spoiler == True %}
          <div class="spoiler"><img src="{% static 'app/images/spoilerr.png' %}" width="100px" /></div>
        {% endif %}
        <!-- 其余模板内容不变 -->

方案二:自定义模板过滤器(适合多场景复用)

如果多个模型或模板都需要提取首图的功能,可以用自定义过滤器:

步骤1:创建模板过滤器文件

在你的app目录下新建templatetags文件夹,里面创建两个文件:

  • __init__.py(空文件即可)
  • custom_filters.py(编写过滤器逻辑)

custom_filters.py内容:

from django import template
from bs4 import BeautifulSoup

register = template.Library()

@register.filter
def get_first_image(content):
    if not content:
        return None
    soup = BeautifulSoup(content, 'html.parser')
    first_img = soup.find('img')
    return first_img['src'] if first_img else None

步骤2:在模板中使用过滤器

首先在模板顶部加载过滤器,然后在图片标签中使用:

{% load custom_filters %} <!-- 放在模板开头 -->

{% for film in query %}
      <div class="elements">
        <div class="thumb">
          <img src="{% if film.content|get_first_image %}{{ film.content|get_first_image }}{% else %}{% static 'app/images/movie-poster.jpg' %}{% endif %}" width="100px" />
        </div>
        <!-- 其余模板内容不变 -->

注意事项

  • 确保CKEditor上传的图片路径是可访问的(如果是相对路径,要保证和当前站点域名匹配)
  • 用BeautifulSoup解析HTML比直接字符串分割更可靠,能应对各种HTML结构变化
  • 两种方案都遵循了Django的MVC原则,将业务逻辑从模板中剥离,更易维护和调试

内容的提问来源于stack exchange,提问作者Ayat Rahman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 06:50:26