Flask-WTF如何展示Request与Client关联表的查询结果?
在Flask-WTF中展示关联数据库表的查询结果
首先,咱们得先把关联的数据从数据库里查出来,再结合Flask-WTF来展示——不管是做只读的详情表单,还是带筛选功能的列表页面,都很容易实现。
第一步:路由里搞定关联查询
根据你定义的Request和Client模型(一对多关联,Client有requests关系,Request有requestClient反向引用),有两种常用的查询方式:
从客户出发,获取其所有请求
利用Client模型里的requests关系(因为你设了lazy='dynamic',还能链式加过滤条件):
@app.route('/') def show_clients_with_requests(): # 拿到所有客户,每个客户都能带出关联的请求 clients = Client.query.all() # 要是想过滤,比如只显示有请求记录的客户: # clients = Client.query.filter(Client.requests.any()).all() return render_template('client_requests.html', clients=clients)
从请求出发,获取对应的客户
为了避免N+1查询(也就是查完请求再挨个查客户),用joinedload预加载关联的Client:
from sqlalchemy.orm import joinedload @app.route('/requests') def show_requests_with_clients(): # 预加载关联的Client,提升查询效率 requests = Request.query.options(joinedload(Request.requestClient)).all() # 也可以加过滤,比如只看已发送报价的请求: # requests = Request.query.filter(Request.offerSent == True).options(joinedload(Request.requestClient)).all() return render_template('requests_with_clients.html', requests=requests)
第二步:用Flask-WTF展示结果
Flask-WTF不仅能做提交表单,用来展示数据(只读)或者结合筛选功能也很方便,分两种场景说:
场景1:用只读表单展示单条关联详情
比如你想展示某条请求对应的客户信息,先建个表单类:
from flask_wtf import FlaskForm from wtforms import StringField, BooleanField class RequestClientForm(FlaskForm): client_lastname = StringField('客户姓氏', render_kw={'readonly': True}) client_prename = StringField('客户名字', render_kw={'readonly': True}) offer_sent = BooleanField('是否已发送报价', render_kw={'disabled': True})
然后在路由里把数据库的数据填到表单里:
@app.route('/request/<int:request_id>') def show_request_detail(request_id): # 拿到请求及其关联的客户,找不到就返回404 request = Request.query.options(joinedload(Request.requestClient)).get_or_404(request_id) form = RequestClientForm() # 把数据库的值赋值给表单字段 form.client_lastname.data = request.requestClient.lastname form.client_prename.data = request.requestClient.prename form.offer_sent.data = request.offerSent return render_template('request_detail.html', form=form)
最后在模板request_detail.html里渲染表单:
<form method="POST"> {{ form.hidden_tag() }} <div class="form-group"> {{ form.client_lastname.label }} {{ form.client_lastname(class="form-control") }} </div> <div class="form-group"> {{ form.client_prename.label }} {{ form.client_prename(class="form-control") }} </div> <div class="form-check"> {{ form.offer_sent.label(class="form-check-label") }} {{ form.offer_sent(class="form-check-input") }} </div> </form>
场景2:结合筛选表单展示关联列表
如果要展示所有客户及其请求,还想加个筛选功能(比如只看有已发送报价的客户),先建筛选表单:
class ClientFilterForm(FlaskForm): has_offer_sent = BooleanField('只显示已发送报价的客户')
然后路由里处理筛选逻辑:
@app.route('/') def show_clients(): form = ClientFilterForm() query = Client.query # 如果勾选了筛选条件,就过滤查询 if form.has_offer_sent.data: query = query.filter(Client.requests.any(Request.offerSent == True)) clients = query.all() return render_template('clients_list.html', form=form, clients=clients)
模板clients_list.html里既渲染筛选表单,又循环展示关联数据:
<form method="GET" class="mb-3"> {{ form.has_offer_sent(class="form-check-input") }} {{ form.has_offer_sent.label(class="form-check-label") }} <button type="submit" class="btn btn-primary ml-2">筛选</button> </form> <div class="list-group"> {% for client in clients %} <div class="list-group-item"> <h5>{{ client.prename }} {{ client.lastname }}</h5> <small class="text-muted">关联请求:</small> <ul class="mt-2"> {% for request in client.requests %} <li>请求ID: {{ request.id }} | 已发报价: {{ '是' if request.offerSent else '否' }}</li> {% else %} <li>暂无请求记录</li> {% endfor %} </ul> </div> {% endfor %} </div>
这样就能完美结合Flask-WTF展示关联表的查询结果啦~
内容的提问来源于stack exchange,提问作者hans2k6
相关产品推荐
相关产品推荐

