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

如何实现无需点击搜索按钮的自动图书搜索功能?

实现实时图书搜索功能的修改方案

问题核心

当前代码仅定义了callSearchAPI函数但未实现,后端也未处理关键词搜索逻辑,需要前后端配合实现AJAX实时请求与结果更新。

步骤1:修改后端视图(views.py)

扩展现有视图,支持关键词模糊搜索,并针对AJAX请求返回JSON数据:

from django.core.paginator import Paginator
from django.http import JsonResponse
from django.shortcuts import render
from .models import Bookk

def index(request):
    # 获取搜索关键词
    query = request.GET.get('q', '').strip()
    
    # 根据关键词过滤图书
    if query:
        books_ = Bookk.objects.filter(book_title__icontains=query)
    else:
        books_ = Bookk.objects.all()
    
    # 分页处理
    paginator = Paginator(books_, 20)
    page = request.GET.get('page', 1)
    books = paginator.get_page(page)
    
    # 处理AJAX请求(实时搜索)
    if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
        book_data = []
        for book in books:
            book_data.append({
                'book_cover': book.book_cover,
                'book_title': book.book_title,
                'stock': book.stock
            })
        return JsonResponse({
            'books': book_data,
            'count': len(books)
        })
    
    # 非AJAX请求返回完整页面
    context = {
        "data": books,
        "search": query
    }
    return render(request, 'index.html', context)

步骤2:添加前端JavaScript实现实时搜索

在HTML页面的</body>标签前插入以下代码,实现防抖请求与结果更新:

<script>
// 防抖函数:避免输入时频繁发送请求
function debounce(func, delay) {
    let timeoutId;
    return function(...args) {
        clearTimeout(timeoutId);
        timeoutId = setTimeout(() => func.apply(this, args), delay);
    };
}

// 执行搜索并更新页面结果
function performSearch(event) {
    const query = event.target.value.trim();
    const resultsContainer = document.querySelector('.container.text-center');
    
    // 关键词为空时恢复显示全部图书
    if (!query) {
        window.location.href = window.location.pathname;
        return;
    }

    // 发送AJAX请求
    fetch(`?q=${encodeURIComponent(query)}`, {
        headers: {
            'X-Requested-With': 'XMLHttpRequest'
        }
    })
    .then(response => response.json())
    .then(data => {
        resultsContainer.innerHTML = '';
        
        if (data.count === 0) {
            resultsContainer.innerHTML = '<h3 class="text-center mt-5">Not found.</h3>';
            return;
        }

        // 生成图书卡片HTML
        let booksHtml = '';
        data.books.forEach(book => {
            // 模拟原模板的text_short过滤器(截取20字符)
            const shortTitle = book.book_title.length > 20 
                ? book.book_title.slice(0, 20) + '...' 
                : book.book_title;
            
            booksHtml += `
                <div class="book-wrapper text-center">
                    <div class="coverpage">
                        <img src="${book.book_cover}"/>
                    </div>
                    <a>${shortTitle}</a>
                    <p>${book.stock}</p>
                </div>
            `;
        });
        resultsContainer.innerHTML = booksHtml;
    })
    .catch(err => console.error('搜索请求失败:', err));
}

// 给输入框绑定防抖后的搜索事件
document.getElementById('textInput').addEventListener('keyup', debounce(performSearch, 300));
</script>

步骤3:调整前端模板细节

  1. 移除冗余事件绑定:删除输入框的onkeyup="callSearchAPI(event)"属性,改用JS绑定的防抖事件
  2. 修复HTML语法错误:原模板中style属性存在多余的&quot;(如<div style="text-align: center;&quot;&gt;),需删除多余引号,否则样式会失效
  3. 可选:扩展下拉建议:如果需要用#dropdown显示搜索建议,可在JS中生成对应HTML插入该容器

额外优化建议

  • 设置最小搜索长度(如≥2个字符),减少无效请求
  • 添加加载状态提示,提升用户体验
  • 扩展搜索字段(如作者、ISBN),修改后端filter条件为Q(book_title__icontains=query) | Q(author__icontains=query)(需导入django.db.models.Q)
  • 若保留分页,需修改分页按钮点击事件为AJAX请求,避免页面刷新

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 19:30:02