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

如何通过JS异步调用Wagtail Page模型方法实现图片懒加载?

在Wagtail中基于RoutablePageMixin实现图片懒加载

看起来你已经找对了方向——用RoutablePageMixin来实现懒加载的后端接口是个很棒的选择!我来帮你把这个功能补全,分步骤推进:

首先看你的现有代码基础

你的Gallery页面模型已经搭好了路由框架,JS也有了初步的点击事件绑定,接下来只需要完善前后端的逻辑就行:

现有Page模型代码

class Gallery(RoutablePageMixin, Page):
    #为便于阅读已移除其他代码
    @route(r'^gallery/loadImages/')
    def lazy_load_images(self, request):
        pass
    class Meta:
        verbose_name = "Gallery"

待完善的JS代码

(function($) {
    $('#lazyLoadLink').on('click', function() {
        // 这里打算写调用后端接口的逻辑
    });
})(jQuery);

1. 完善后端lazy_load_images接口

首先要让这个路由方法返回前端需要的图片数据,我们用JSON格式来传输,同时加上分页逻辑避免一次性加载所有图片:

from django.http import JsonResponse

class Gallery(RoutablePageMixin, Page):
    # 你的其他字段和配置...

    @route(r'^gallery/loadImages/$')  # 加上结尾的$,避免匹配到类似/gallery/loadImages/extra这样的路径
    def lazy_load_images(self, request):
        # 从请求参数里获取分页信息,默认第一页,每页8张图
        current_page = int(request.GET.get('page', 1))
        per_page = int(request.GET.get('limit', 8))
        
        # 假设你的Gallery页面通过名为`images`的字段关联了Wagtail Image模型
        # 这里按分页截取图片数据
        start_idx = (current_page - 1) * per_page
        end_idx = start_idx + per_page
        paginated_images = self.images.all()[start_idx:end_idx]
        
        # 把图片转换成前端能直接用的格式,包含缩略图URL、alt文本等
        image_list = []
        for img in paginated_images:
            # 这里用Wagtail的图片渲染方法生成指定尺寸的缩略图
            rendition = img.get_rendition('fill-400x300|jpegquality-80')
            image_list.append({
                'url': rendition.url,
                'alt': img.title,
                'width': rendition.width,
                'height': rendition.height
            })
        
        # 返回JSON响应,同时标记是否还有更多图片可以加载
        return JsonResponse({
            'images': image_list,
            'has_more': len(paginated_images) == per_page
        })

2. 补全前端JS逻辑

接下来完善点击事件,实现异步请求后端接口、渲染图片的功能,同时处理加载状态和无更多数据的情况:

(function($) {
    let currentPage = 1;
    const perPage = 8;
    const $loadBtn = $('#lazyLoadLink');
    const $galleryWrap = $('#galleryContainer'); // 页面上用来放图片的容器

    $loadBtn.on('click', function(e) {
        e.preventDefault();
        // 禁用按钮防止重复点击
        $loadBtn.prop('disabled', true).text('加载中...');

        $.ajax({
            url: `/gallery/loadImages/?page=${currentPage}&limit=${perPage}`,
            method: 'GET',
            dataType: 'json',
            success: function(res) {
                // 把返回的图片逐个渲染到容器里
                res.images.forEach(img => {
                    const $img = $(`<img src="${img.url}" alt="${img.alt}" width="${img.width}" height="${img.height}" class="gallery-item">`);
                    $galleryWrap.append($img);
                });

                // 页码自增
                currentPage++;

                // 如果没有更多图片,隐藏加载按钮
                if (!res.has_more) {
                    $loadBtn.hide();
                }

                // 恢复按钮状态
                $loadBtn.prop('disabled', false).text('加载更多图片');
            },
            error: function() {
                alert('图片加载失败,请稍后重试');
                $loadBtn.prop('disabled', false).text('加载更多图片');
            }
        });
    });
})(jQuery);

3. 页面模板配合

最后在Gallery页面的模板里,要准备好图片容器和加载按钮,同时可以先渲染第一页的图片,让页面初始有内容:

<!-- 图片容器 -->
<div id="galleryContainer" class="grid-container">
    <!-- 先渲染第一页的图片 -->
    {% for img in page.images.all|slice:":8" %}
        <img src="{{ img.get_rendition('fill-400x300|jpegquality-80').url }}" alt="{{ img.title }}" class="gallery-item">
    {% endfor %}
</div>

<!-- 只有当图片总数超过8张时才显示加载按钮 -->
{% if page.images.all|length > 8 %}
    <a href="#" id="lazyLoadLink" class="load-more-btn">加载更多图片</a>
{% endif %}

这样一套下来,你的图片懒加载功能就可以正常工作了——点击按钮时会异步加载下一页的图片,直到所有图片都加载完,按钮会自动隐藏。

内容的提问来源于stack exchange,提问作者Henry Lynx

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:23:55