如何为Flask网站实现按manga_name不区分大小写的搜索功能?
实现Flask网站搜索栏功能
需求说明
现有基于Flask框架和MySQL数据库的网站,数据库模型Image包含manga_name字段,首页路由index返回所有Image数据;模板中存在ID为searchBar的输入框但未实现功能。需要实现:用户按下回车键时,返回所有与输入内容(不区分大小写)匹配manga_name的条目,且仅展示不同post_name的内容。
代码修改步骤
1. 更新首页路由代码
修改index路由,处理搜索请求,根据关键词过滤Image数据:
@app.route("/", methods=["GET"]) def index(): # 获取搜索关键词,默认空字符串 search_query = request.args.get("search", "").strip() if search_query: # 不区分大小写匹配manga_name(MySQL原生支持ILIKE) posts = Image.query.filter(Image.manga_name.ilike(f"%{search_query}%")).all() else: # 无搜索时返回全部数据 posts = Image.query.all() # 整理模板渲染所需数据 context = {"posts": posts} if current_user.is_authenticated: context["current_user"] = current_user return render_template("index.html", **context)
2. 修改模板代码
方案一:用表单实现回车提交(无需JS)
给搜索框包裹表单,利用浏览器默认回车提交行为:
<div id="first"> <form method="GET" action="{{ url_for('index') }}"> <input type="text" id="searchBar" name="search" placeholder="搜索漫画名..." value="{{ request.args.get('search', '') }}"> <!-- 隐藏提交按钮,仅通过回车触发 --> <button type="submit" style="display: none;">搜索</button> </form> {% if current_user.is_authenticated %} <a href="{{ url_for('user', username=current_user.username) }}"><img src="{{ url_for('static', filename='profile-icon.png') }}" alt="" id="profileIcon"></a> <a href="{{ url_for('logout') }}" id="logout-btn">Logout</a> {% else %} <a href="{{ url_for('login') }}"><img src="{{ url_for('static', filename='profile-icon.png') }}" alt="" id="profileIcon"></a> {% endif %} </div>
方案二:用JS监听回车键事件
若不想使用表单,可通过JavaScript监听回车动作并跳转搜索:
<div id="first"> <input type="text" id="searchBar" name="searchBar" placeholder="搜索漫画名..." value="{{ request.args.get('search', '') }}"> {% if current_user.is_authenticated %} <a href="{{ url_for('user', username=current_user.username) }}"><img src="{{ url_for('static', filename='profile-icon.png') }}" alt="" id="profileIcon"></a> <a href="{{ url_for('logout') }}" id="logout-btn">Logout</a> {% else %} <a href="{{ url_for('login') }}"><img src="{{ url_for('static', filename='profile-icon.png') }}" alt="" id="profileIcon"></a> {% endif %} </div> <script> const searchBar = document.getElementById('searchBar'); searchBar.addEventListener('keypress', function(e) { if (e.key === 'Enter') { const query = encodeURIComponent(this.value.trim()); window.location.href = "{{ url_for('index') }}?search=" + query; } }); </script>
3. 保留原有渲染逻辑
原模板中{% if loop.changed(post.post_name) %}已经实现了不同post_name条目的去重展示,无需修改这部分代码,搜索结果会自动沿用该逻辑,仅显示每个post_name对应的首个条目。
关键细节说明
- 不区分大小写匹配:使用
ilike适配MySQL,若使用SQLite,需改为filter(func.lower(Image.manga_name).contains(func.lower(search_query)))(需提前导入from sqlalchemy import func)。 - 搜索词保留:输入框的
value="{{ request.args.get('search', '') }}"可在搜索后保留用户输入内容,优化体验。 - 请求方式:采用GET请求处理搜索,符合REST规范,支持浏览器书签保存搜索结果。
内容的提问来源于stack exchange,提问作者user19552868
相关产品推荐
相关产品推荐

