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

Flask中Jinja2模板变量无刷新传递至路由的实现方法

实现无刷新点赞的方案(基于Flask + AJAX)

要实现不刷新页面传递变量处理点赞,核心思路是用**异步JavaScript请求(AJAX)**和Flask后端通信,完成数据传递与逻辑处理后,再局部更新页面内容。下面是具体的分步实现:

1. Flask后端:添加处理点赞的专属路由

首先在你的Flask应用里新增一个专门处理点赞请求的路由,它接收前端传来的结果标识(比如结果ID,也就是你要传递的变量),完成点赞逻辑(比如更新数据库计数),最后返回JSON格式的响应(比如更新后的点赞数或操作状态)。

from flask import Flask, render_template, request, jsonify

app = Flask(__name__)
# 这里用字典模拟存储搜索结果与点赞数的数据库,实际项目请替换为真实数据库操作
search_results_db = {
    1: {"content": "搜索结果1", "likes": 0},
    2: {"content": "搜索结果2", "likes": 0},
    3: {"content": "搜索结果3", "likes": 0}
}

# 原有搜索路由
@app.route('/', methods=['GET', 'POST'])
def search():
    results = []
    if request.method == 'POST':
        query = request.form.get('query')
        # 模拟搜索匹配逻辑
        results = [v for k, v in search_results_db.items() if query in v['content']]
    return render_template('search.html', results=results)

# 处理点赞的异步路由
@app.route('/like-result', methods=['POST'])
def like_result():
    # 接收前端传来的结果ID(即要传递的变量)
    result_id = request.json.get('result_id')
    if result_id not in search_results_db:
        return jsonify({'success': False, 'message': '目标结果不存在'})
    
    # 执行点赞逻辑(这里模拟增加点赞数)
    search_results_db[result_id]['likes'] += 1
    return jsonify({
        'success': True,
        'new_likes': search_results_db[result_id]['likes']
    })

if __name__ == '__main__':
    app.run(debug=True)

2. 前端模板:配置结果列表与点赞交互

在你的搜索模板(比如search.html)中,给每个搜索结果的点赞按钮添加数据属性来存储要传递的变量(比如结果ID),同时用JavaScript绑定点击事件,发起异步请求。

注意:如果使用Flask-WTF做表单验证,必须添加CSRF令牌,否则POST请求会被拦截。

<!DOCTYPE html>
<html>
<head>
    <title>搜索页面</title>
    <!-- 如果用Flask-WTF,添加CSRF令牌meta标签 -->
    <!-- <meta name="csrf-token" content="{{ csrf_token() }}"> -->
</head>
<body>
    <!-- 搜索表单 -->
    <form class="form-container" method="POST">
        <input type="text" name="query" placeholder="输入搜索内容">
        <button type="submit">搜索</button>
    </form>

    <!-- 搜索结果列表 -->
    {% if results %}
    <ul class="results-list">
        {% for idx, result in enumerate(results, start=1) %}
        <li class="result-item" data-result-id="{{ idx }}">
            <p>{{ result.content }}</p>
            <div class="like-group">
                <button class="like-btn">点赞</button>
                <span class="like-count">点赞数:{{ result.likes }}</span>
            </div>
        </li>
        {% endfor %}
    </ul>
    {% endif %}

    <!-- 异步请求逻辑 -->
    <script>
        // 获取所有点赞按钮
        const likeBtns = document.querySelectorAll('.like-btn');
        
        likeBtns.forEach(btn => {
            btn.addEventListener('click', async function(e) {
                e.preventDefault();
                // 从父元素的data属性中获取要传递的结果ID
                const resultItem = this.closest('.result-item');
                const resultId = parseInt(resultItem.dataset.resultId);
                
                try {
                    // 发起异步POST请求
                    const response = await fetch('/like-result', {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json',
                            // 如果用Flask-WTF,带上CSRF令牌
                            // 'X-CSRFToken': document.querySelector('meta[name="csrf-token"]').content
                        },
                        body: JSON.stringify({ result_id: resultId })
                    });
                    
                    const resData = await response.json();
                    if (resData.success) {
                        // 局部更新点赞数,无需刷新整个页面
                        const countElement = resultItem.querySelector('.like-count');
                        countElement.textContent = `点赞数:${resData.new_likes}`;
                    } else {
                        alert(resData.message);
                    }
                } catch (err) {
                    console.error('点赞请求出错:', err);
                    alert('点赞失败,请稍后重试');
                }
            });
        });
    </script>
</body>
</html>

关键细节说明

  • 变量传递: 通过data-*属性(比如data-result-id)把结果标识绑定到DOM元素上,点击按钮时读取这个值,以JSON格式发送给后端。
  • 异步请求: 使用现代的fetch API发起异步请求,避免页面刷新;如果习惯jQuery,也可以用$.ajax替代。
  • 局部更新: 后端处理完成后返回新的点赞数,前端直接修改对应结果的点赞数字段,实现无刷新的实时更新。
  • CSRF防护: 若使用Flask-WTF,必须在模板中添加CSRF令牌meta标签,并在请求头中携带该令牌,否则请求会被Flask的CSRF保护机制拦截。

这样就能实现用户点击点赞按钮时,不刷新整个页面就把结果变量传递给Flask路由处理,同时实时更新页面内容啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:32:21