我一直在摸索,试图弄清楚如何首先获取从搜索返回的JSON数据(现在已经解决了,谢天谢地),然后使用喷出的JSON更新我的jinja模板。
我已经尝试了几种方法,但是我似乎正在四处逛逛,由于我对AJAX或Flask的经验都不多,所以我往往会引起更多无法解决的问题。
我有一个AJAX文件,但我不认为它能正常工作(即使它是正确的),但是我猜想这需要指示以获取数据并将其放入正确的表/区域中。渲染的模板?我的问题是我该如何实现?
下面是我的app.py
from flask import request, jsonify
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_bootstrap import Bootstrap
from flask import render_template
from sqlalchemy import create_engine
from flask_marshmallow import Marshmallow
import json
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI']='postgresql://postgres:test@localhost/postgres'
engine = create_engine('postgresql+psycopg2://postgres:test@localhost/postgres')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.debug = True
app.config['SQLALCHEMY_ECHO'] = True
db=SQLAlchemy(app)
Bootstrap(app)
ma=Marshmallow(app)
# classes
class Sdctest(db.Model):
startchass= db.Column (db.Text, primary_key=True)
cusname= db.Column (db.Text)
chassistype1= db.Column (db.Text)
axleqty= db.Column (db.Integer)
tyres= db.Column (db.Text)
extlength= db.Column (db.Text)
neck= db.Column (db.Text)
stepheight= db.Column (db.Text)
reardeckheight= db.Column (db.Text)
siderave= db.Column (db.Text)
steer= db.Column (db.Text)
sockets= db.Column (db.Text)
containerstwistlock= db.Column (db.Text)
headboard= db.Column (db.Text)
class TableSchema(ma.Schema):
class Meta:
fields = ('startchass', 'cusname', 'chassistype1', 'axleqty', 'tyres', 'extlength', 'neck', 'stepheight', 'reardeckheight', 'siderave', 'steer', 'sockets', 'containerstwistlock', 'headboard')
tables = TableSchema()
tabless = TableSchema(many=True)
#routes
@app.route('/')
def index():
return render_template('index.html')
@app.route('/platform', methods=['GET', 'POST'])
def curtainsider():
options = db.session.query(Sdctest.chassistype1).distinct().all()
axleopts = db.session.query(Sdctest.axleqty).distinct().all()
# enables passing user input to the variable
if request.method == 'POST':
# query parameters and their corresponding database columns
param_columns = {
"startchass": "startchass",
"cusname": "cusname",
"chassistype1": "chassistype1",
"axleqty": "axleqty",
"tyres": "tyres",
"siderave": "siderave",
"steer": "steer",
"sockets": "sockets",
"containerstwistlock":"containerstwistlock",
"headboard": "headboard",
}
param_column2 = {
"startchass": "startchass",
"extlength": "extlength",
"neck": "neck",
"stepheight": "stepheight",
"reardeckheight": "reardeckheight",
}
# Get all of the column filters where the parameters aren't empty
filters = {
column: request.form[param]
for param, column in param_columns.items()
if request.form.get(param, "") != ""
}
filters2 = {
column: request.form[param]
for param, column in param_column2.items()
if request.form.get(param, "") != ""
}
#filter most columns using fuzzy match
query = Sdctest.query
for column, value in filters.items():
query = query.filter(getattr(Sdctest, column).ilike(f'%{value}%')) .order_by(Sdctest.startchass.desc())
for column, value in filters2.items():
query = query.filter(getattr(Sdctest, column).ilike(f'{value}')).order_by(Sdctest.startchass.desc())
results2 = query.all()
result2 = tabless.dump(results2, object)
# renders the template
return render_template('platform.html')
return jsonify(result2)
else:
return render_template('platform.html', options=options)
if __name__ == "__main__":
run_server()`
这是我的模板:
<!DOCTYPE html>
<html lang="en">
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<style>
body {
padding: 15px;
background-image: url("/static/bg.png");
background-repeat: no-repeat;
}
.table-hideable td,
.table-hideable th {
width: auto;
transition: width .5s, margin .5s;
}
.btn-condensed.btn-condensed {
padding: 0px 0px 0px 0px;
box-shadow: none;
}
.hide-col {
width: 0 !important;
height: 0 !important;
display: none !important;
overflow: hidden !important;
margin: 0 !important;
padding: 0 !important;
border: none !important;
}
.thbg
{
background-image: url("/static/fieldbg.png");
}
.thbgg
{
background-color:#b21f2d ;
color: #FFF;
}
</style>
<link rel="stylesheet" href={{ url_for('static', filename='css/bootstrap.css') }}>
<script defer src="https://use.fontawesome.com/releases/v5.0.13/js/all.js" integrity="sha384-xymdQtn1n3lH2wcu0qhcdaOpQwyoarkgLVxC/wZ5q7h9gHtxICrpcaSUfygqZGOe" crossorigin="anonymous"></script>
<meta charset="UTF-8">
<title>Sales Search</title>
</head>
<body>
<div id="wrapper">
<div class="corner-ribbon top-left red shadow">ALPHA</div>
<div align="center" class="p"><img src="/static/sdclogopng.png"> </div>
<div class="container-fluid" id="container-fluid">
<div class="row">
<div class="col-sm-9">
<div class="form-group">
<form method="POST" class="form-horizontal" role="form" name="form" id="form">
<div class="form-row form-group">
<div class="col-auto">
<input type="text" name="startchass" class="form-control form-control-sm thbg" placeholder="Chassis Number">
</div>
<div class="col-auto">
<input type="text" name="cusname" class="form-control form-control-sm thbg" placeholder="Customer name">
</div>
<div class="col-auto">
<select name="chassistype1" class="form-control form-control-sm thbg" title="chassis type">
<option disabled selected value>Select chassis type</option>
{% for option in options %}
<option class="form-control form-control-sm thbg" value="{{ option[0] }}">{{ option[0] }}</option>
{% endfor %}
</select>
</div>
<div class="col-auto">
<select name="axleqty" class="form-control form-control-sm thbg" title="chassis type">
<option disabled selected value>Axle quantity</option>
{% for axleopt in axleopts %}
<option class="form-control form-control-sm thbg" value="{{ axleopt[0] }}">{{ axleopt[0] }}</option>
{% endfor %}
</select>
</div>
<div class="col-auto">
<input type="text" name="tyres" class="form-control form-control-sm thbg" placeholder="tyre type" id="1">
</div></div>
<div class="form-row form-group">
<div class="col-auto">
<input type="text" name="extlength" class="form-control form-control-sm thbg" placeholder="External Length" id="2">
</div>
<div class="col-auto">
<input type="text" name="neck" class="form-control form-control-sm thbg" placeholder="Neck Dimensions" id="3">
</div>
<div class="col-auto">
<input type="text" name="stepheight" class="form-control form-control-sm thbg" placeholder="Step height" id="3">
</div>
<div class="col-auto">
<input type="text" name="reardeckheight" class="form-control form-control-sm thbg" placeholder="reardeckheight" id="4">
</div>
<div class="col-auto">
<input type="text" name="siderave" class="form-control form-control-sm thbg" placeholder="Siderave" id="5">
</div></div>
<div class="form-row form-group">
<div class="col-auto">
<input type="text" name="steer" class="form-control form-control-sm thbg" placeholder="Steer option" id="6">
</div>
<div class="col-auto">
<input type="text" name="sockets" class="form-control form-control-sm thbg" placeholder="Socket count" id="7">
</div>
<div class="col-auto">
<input type="text" name="containertwistlock" class="form-control form-control-sm thbg" placeholder="Twist locks" id="8">
</div>
<div class="col-auto">
<input type="text" name="headboard" class="form-control form-control-sm thbg" placeholder="headboard" id="9">
</div>
<input type="submit" value="Search" class="btn btn-danger btn-sm" id="button" name="button" type="button"></div>
</form>
</div></div><div class=col-sm-3> <div class="refinewidth"> <h6 style="color:#fff">search for specific items/text here:</h6>
<input class="form-control form-control-sm thbg" id="myInput" type="text" placeholder="Search.."></div><br></div></div></div>
<div class="col-sm-4 alert alert-info"><strong>Click on a column header to exclude it from your results</strong></div>
{% block body %}
<div class="table-responsive">
<table class="table table-condensed table-hover table-bordered table-hideable table-sm">
<thead class="table-hideable thbgg">
<tr>
<th class="hide-column">Chassis Number </th>
<th class="hide-column">Customer name</th>
<th class="hide-column">Chassis Type</th>
<th class="hide-column">Axles</th>
<th class="hide-column">Tyre</th>
<th class="hide-column">External Length</th>
<th class="hide-column">Neck</th>
<th class="hide-column">Step height</th>
<th class="hide-column">Rear Deck height</th>
<th class="hide-column">Siderave</th>
<th class="hide-column">Steer</th>
<th class="hide-column">Sockets</th>
<th class="hide-column">Twistlocks</th>
<th class="hide-column">Headboard</th>
</tr>
</thead>
<tbody id="myTable">
{% for item in result2 %}
<tr>
<td class>{{ item.startchass }}</td><td>{{ item.cusname }}</td><td>{{ item.chassistype1 }}<td>{{ item.axleqty }}</td><td>{{ item.tyres }}</td><td>{{ item.extlength }}</td><td>{{ item.neck }}</td><td>{{ item.stepheight }}</td><td>{{ item.reardeckheight }}</td><td>{{ item.siderave }}</td><td>{{ item.steer }}</td><td>{{ item.sockets }}</td><td>{{ item.containerstwistlock }}</td><td>{{ item.headboard }}</td>
</tr>
{% endfor %}
</tbody>
<tfoot class="show-column-footer">
<tr>
<th colspan="14"><a class="show-column" href="#">Click here to show hidden columns</a></th>
</tr>
</tfoot>
</table>
</div>
{% endblock %}
<script>
$(document).ready(function(){
$("#myInput").on("keyup", function() {
var value = $(this).val().toLowerCase();
$("#myTable tr").filter(function() {
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
});
});
});
</script>
<script type=text/javascript src="{{ url_for('static', filename='ajax.js') }}"></script>
<script type=text/javascript src="{{ url_for('static', filename='form.js') }}"></script>
</div>
</body>
</html>
最后是我的(可能无法使用)AJAX文件:
$(function() {
$('form').on('submit', function(e){
$.ajax({
url: '/platform',
data: $('form').serialize(),
type: 'POST',
cusname:cusname,
success: function(response) {
console.log(response);
},
error: function(error) {
console.log(error);
}
});
});
});
答案 0 :(得分:1)
我不完全了解您要实现的目标,但是我猜您尝试使用搜索框输入并将其用于查询数据库并将JSON返回表中吗? 如果这不是您要实现的目标,请回答上面我提到的四个问题。 另外,我强烈建议您在搜索框中使用某种形式的验证,因为它直接进入查询(DB)。您可以使用Flask-WTF(更好的服务器端表单验证),甚至可以使用客户端表单验证库(更弱)。
上面是您需要考虑的情况,下面是最小化的示例。
Ajax
$(function() {
// please do not use form as an ID as this may be a potential error later on.
$('#form').on('submit', function(e){
$.ajax({
url: '/platform', //not a good practice to use /platform, but instead use "{{url_for('.curtainsider')}}"
data: $('form').serialize(), //removed cusname, if you need to pass cusname into the server, create a hidden input field and include it inside <form></form>
type: 'POST',
success: function(response) {
var dbData = response.result;
// do your thing here with the data that was passed from curtainsider()
},
error: function(error) {
console.log(error);
}
});
});
});
查看
@app.route('/platform', methods=['GET', 'POST'])
def curtainsider():
# to parse the serialized form.
if request.method == 'POST':
data_one = request.form['data_one']
cusname = request.form['cusname']
# and so on....
# make DB queries based on your input
return jsonify({'result': db_data})
以下是受CSRF保护的时间。
如果您的表单受CSRF保护,则将以下代码附加到ajax函数的末尾。并且还将{{form.csrf_token}}
包含在HTML的表单元素中。
$.ajaxSetup({
beforeSend: function (xhr, settings) {
if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", "{{ form.csrf_token._value() }}")
}
}
});