如何通过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
相关产品推荐
相关产品推荐

