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

如何在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>

关键说明

  1. Session存储:利用Flask会话保存用户的历史请求数据,确保多次请求间数据不丢失。
  2. 去重逻辑:通过字典键的唯一性,以文章id为键存储所有文章,自动过滤重复项。
  3. 空值处理:增加标签为空的判断,避免直接调用request.form['tags']抛出异常。
  4. 清空功能:提供重置入口,方便用户重新筛选标签。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 10:40:25