首页 > 解决方案 > 将 JSON 发布到烧瓶模板

问题描述

我一直在努力想办法首先从我的搜索中获取 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);
            }
        });
    });
});

标签: pythonjsonajaxflasksqlalchemy

解决方案


我不完全理解您要实现的目标,但我猜您尝试使用搜索框输入并使用这些输入来查询数据库并将 JSON 返回到表中?如果这不是您想要达到的目标,请回答我在上面评论过的四个问题。另外,我强烈建议您在搜索框中使用某种验证,因为它直接进入您的查询 (DB)。您可以使用 Flask-WTF(服务器端表单验证 - 更好)甚至客户端表单验证库(较弱)。

考虑到上面是你的情况,下面是最小化的例子。

阿贾克斯

$(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() }}")
        }
    }
});

推荐阅读