如何在Python中合并无重复字典?Flask+Jinja2场景实现
解决Flask中合并多标签请求的无重复JSON数据问题
我用Flask和Jinja2搭建了一个页面,从外部接口https://api.hatchways.io/assessment/blog/posts获取带标签的文章JSON数据,希望实现按标签过滤并合并多次请求结果、自动去重的功能。目前点击标签按钮或搜索标签时,只能显示当前标签的结果,无法保留之前请求的内容并合并。
现有代码
main.py
from flask import Flask, render_template, request import requests app = Flask(__name__) @app.route('/api', methods=['GET', 'POST']) def add_tag(): name = request.form['tags'] # form = APInameForm() # 代码中未定义该表单类,暂时注释 url= 'https://api.hatchways.io/assessment/blog/posts?tag='+name try: api = requests.get(url).json() api = api['posts'] ilist = [] for i in api: ilist.append(i) if not ilist: output = '{<br>' output = output + '"error": "Tags parameter is required" <br>' output = output + '}' return output return render_template('/index.html', test=ilist) except requests.ConnectionError: return "Connection Error" @app.route('/') def index(): return render_template("index.html") if __name__ == '__main__': app.run(debug=True)
index.html
{% extends 'base.html' %} {% block content %} <form class="text-center pt-3" method="POST" action="/api"> <input type="text" class="form-control" placeholder="Search" name="tags"> <input type="submit" value="Search" /> </form> <br/><br/><br/> <h1>Recommended Tags:</h1> <form class="form-inline" method="POST" action="/api"> <div class="control"> <input type="submit" class="btn btn-primary mb-2" name="tags" value="tech"> </div> <div class="control"> <input type="submit" class="btn btn-primary mb-2" name="tags" value="history"> </div> <div class="control"> <input type="submit" class="btn btn-primary mb-2" name="tags" value="startups"> </div> <div class="control"> <input type="submit" class="btn btn-primary mb-2" name="tags" value="health"> </div> <div class="control"> <input type="submit" class="btn btn-primary mb-2" name="tags" value="science"> </div> <div class="control"> <input type="submit" class="btn btn-primary mb-2" name="tags" value="design"> </div> <div class="control"> <input type="submit" class="btn btn-primary mb-2" name="tags" value="culture"> </div> <div class="control"> <input type="submit" class="btn btn-primary mb-2" name="tags" value="history"> </div> </form> <br/><br/><br/> <code> {<br> "posts": [{<br> {% for item in test %} "id": {{ item.id }}<br> "author": "{{ item.author }}"<br> "authorId": {{ item.authorId }}<br> "likes": {{ item.likes }}<br> "popularity" :{{ item.popularity }}<br> "reads": {{ item.reads }}<br> "tags": {{ item.tags }}<br><br> {% endfor %} } ] </code> {% endblock %}
解决方案:用Session存储历史数据并合并去重
核心思路是用Flask的session保存用户已请求过的文章数据,每次新请求时将新数据合并进去,并通过文章id去重(每个文章的id是唯一标识)。
修改后的main.py
from flask import Flask, render_template, request, session import requests app = Flask(__name__) # 必须设置secret_key才能使用session,生产环境请用随机安全字符串 app.secret_key = 'your_custom_secret_key' @app.route('/api', methods=['GET', 'POST']) def add_tag(): # 获取标签并处理空提交 name = request.form.get('tags', '').strip() if not name: output = '{<br>' output += '"error": "Tags parameter is required" <br>' output += '}' return output url = f'https://api.hatchways.io/assessment/blog/posts?tag={name}' try: api_response = requests.get(url).json() new_posts = api_response.get('posts', []) # 从session获取已保存的文章,无数据则初始化为空列表 existing_posts = session.get('posts', []) # 合并并去重:用id作为键,字典自动覆盖重复项,再转成列表 merged_posts_dict = {post['id']: post for post in existing_posts + new_posts} merged_posts = list(merged_posts_dict.values()) # 将合并后的结果存回session session['posts'] = merged_posts return render_template('index.html', test=merged_posts) except requests.ConnectionError: return "Connection Error" @app.route('/') def index(): # 首次访问时传递session中的已有数据,无数据则传空列表 return render_template("index.html", test=session.get('posts', [])) # 可选:添加清空所有结果的路由 @app.route('/clear', methods=['POST']) def clear_posts(): session.pop('posts', None) return render_template("index.html", test=[]) if __name__ == '__main__': app.run(debug=True)
模板新增清空功能(可选)
在index.html的推荐标签表单后添加清空按钮:
<form class="text-center pt-2" method="POST" action="/clear"> <input type="submit" class="btn btn-danger" value="Clear All Posts" /> </form>
关键说明
- Session存储:利用Flask会话保存用户的历史请求数据,确保多次请求间数据不丢失。
- 去重逻辑:通过字典键的唯一性,以文章id为键存储所有文章,自动过滤重复项。
- 空值处理:增加标签为空的判断,避免直接调用
request.form['tags']抛出异常。 - 清空功能:提供重置入口,方便用户重新筛选标签。
内容的提问来源于stack exchange,提问作者LocutusOfBorg
相关产品推荐
相关产品推荐

