如何使用AJAX将表单正确提交给Flask?

时间:2017-06-20 05:10:43

标签: javascript jquery python html ajax

我是Python和AJAX的初学者,为什么当我用app.html运行我的app.py时,我要显示的结果会被整个表单替换?

这是我的代码:

from flask import Flask, render_template, request

app = Flask(__name__, 
template_folder='C:\\Users\\iyzadsyammil\\PycharmProjects\\PVT - Copy')

@app.route('/App',methods=['GET', 'POST'])
def showapp():
error = " "
finalpb= 0
x=0
logpb=0

if request.method == 'POST':
    ingor = request.form['inGOR']

    ingor = float(ingor)

    try:
        finalpb = ingor
    except ValueError:
        error = "Please enter an appropriate value!"

return render_template('app.html',error=error,finalpb=finalpb)

if __name__ == "__main__":
  app.run(debug=True)

这是我的Python Flask文件

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
    <meta name="description" content="">
    <meta name="author" content="">
    <link rel="icon" href="https://media.licdn.com/mpr/mpr/shrink_200_200/AAEAAQAAAAAAAAfJAAAAJDIxMDc1NWExLTczODgtNDBhOS1iZmYwLWRmOTZjZjc2NzVhYQ.png">

    <title>Invigour Tool</title>

    <!-- Bootstrap core CSS -->
    <link href="http://getbootstrap.com/dist/css/bootstrap.min.css" rel="stylesheet">
    <!-- Custom styles for this template -->
    <!--<link href="dashboard.css" rel="stylesheet" type="text/css">-->
    <style>

/* Move down content because we have a fixed navbar that is 50px tall */
body {
  padding-top: 50px;

}

/*
 * Global add-ons
 */

.sub-header {
  padding-bottom: 10px;
  border-bottom: 1px solid #eee;
}

/*
 * Top navigation
 * Hide default border to remove 1px line.
 */
.navbar-fixed-top {
  border: 0;
}

/*
 * Sidebar
 */

/* Hide for mobile, show later */
.sidebar {
  display: none;
}
@media (min-width: 768px) {
  .sidebar {
    position: fixed;
    top: 51px;
    bottom: 0;
    left: 0;
    z-index: 1000;
    display: block;
    padding: 20px;
    overflow-x: hidden;
    overflow-y: auto; /* Scrollable contents if viewport is shorter than content. */
    background-color: #f5f5f5;
    border-right: 1px solid #eee;
  }
}

/* Sidebar navigation */
.nav-sidebar {
  margin-right: -21px; /* 20px padding + 1px border */
  margin-bottom: 20px;
  margin-left: -20px;
}
.nav-sidebar > li > a {
  padding-right: 20px;
  padding-left: 20px;
}
.nav-sidebar > .active > a,
.nav-sidebar > .active > a:hover,
.nav-sidebar > .active > a:focus {
  color: #fff;
  background-color: #428bca;
}

/*
 * Main content
 */

.main {
  padding: 20px;
}
@media (min-width: 768px) {
  .main {
    padding-right: 40px;
    padding-left: 40px;
  }
}
.main .page-header {
  margin-top: 0;
}

/*
 * Placeholder dashboard ideas
 */

.placeholders {
  margin-bottom: 30px;
  text-align: center;
}
.placeholders h4 {
  margin-bottom: 0;
}
.placeholder {
  margin-bottom: 20px;
}
.placeholder img {
  display: inline-block;
  border-radius: 50%;
}

/* Custom page footer */
.footer {
  padding-top: 10px;
  margin-top: 2cm;
  color: #777;
  border-top: 1px solid #e5e5e5;

}

.cal{
    float: right;
    box-shadow: 0 12px 16px 0 rgba(0,0,0,0.24), 0 17px 50px 0 rgba(0,0,0,0.19);
    width: 180px;
    height: 85px;
    font-size: 30px;
    border-radius: 24px;
    background-color: limegreen;
    position: relative;
    right: 0.5cm;
}

.conti{
    float: right;
    box-shadow: 0 12px 16px 0 rgba(0,0,0,0.24), 0 17px 50px 0 rgba(0,0,0,0.19);
    width: 180px;
    height: 85px;
    font-size: 30px;
    border-radius: 24px;
    background-color: limegreen;
}

.rest{
    float: right;
    box-shadow: 0 12px 16px 0 rgba(0,0,0,0.24), 0 17px 50px 0 rgba(0,0,0,0.19);
    width: 180px;
    height: 85px;
    font-size: 30px;
    border-radius: 24px;
    background-color: limegreen;
    margin-top: 3cm;
    position: relative;
    left: 7cm;
}

input[type="number"]{
    margin-left: 3cm;
}

select[id=cor4],[id=cor5]{
    width: 165px;
}

select{
    margin-left: 1cm;
}

p[id=pb],[id=rs],[id=bo],[id=co],[id=uo],[id=po],[id=zf],[id=bg],[id=pg],[id=ug],[id=bw],[id=uw],[id=pw],[id=cw],[id=iow],[id=iog]{
    margin-left: 4cm;
}

tr:hover{
    background-color:#f5f5f5}

    </style>
  </head>

<body>
  <div>

    <nav class="navbar navbar-inverse navbar-fixed-top">
      <div class="container-fluid">
        <div class="navbar-header">
          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
          <a class="navbar-brand" href="http://www.invigourenergy.com/">Invigour Energy</a>
        </div>
        <div id="navbar" class="navbar-collapse collapse">
          <ul class="nav navbar-nav navbar-right">
            <li><a href="Menu">Dashboard</a></li>
            <li><a href="PVT Menu">PVT Tool</a></li>
            <li><a href="#">Help</a></li>
          </ul>
          <form class="navbar-form navbar-right">
            <input type="text" class="form-control" placeholder="Search...">
          </form>
        </div>
      </div>
    </nav>

    <div class="container-fluid">
      <div class="row">
        <div class="col-sm-3 col-md-2 sidebar">
          <ul class="nav nav-sidebar">
            <li class="active"><a href="#">Overview <span class="sr-only">(current)</span></a></li>

            <li><a href="#"> </a></li>
            <li><a href="#"> </a></li>
          </ul>
          <ul class="nav nav-sidebar">
            <li><a href=""> </a></li>
            <li><a href=""> </a></li>
            <li><a href=""> </a></li>
            <li><a href=""> </a></li>
            <li><a href=""> </a></li>
          </ul>
        </div>
        <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
          <form method="POST" class="form" id="fm">
                <h3>Basic PVT Application</h3>
                <br>
                <table>
                    <tr><td><u>Input Data</u></td><td></td><td></td></tr>
                    <tr><td>&nbsp</td></tr>
                    <tr><td>Solution GOR(Rs) </td><td><input type="number" step="any" id="inGOR" name="inGOR"></td><td>scf/bbl</td></tr>
                    <tr><td>Oil Gravity </td><td><input type="number" step="any" id="inOG"></td><td>API</td></tr>
                    <tr><td>Gas Specific Gravity </td><td><input type="number" step="any" id="inGG"></td><td>SG(air=1)</td></tr>
                    <tr><td>Temperature </td><td><input type="number" step="any" id="inT"></td><td>◦F</td></tr>
                    <tr><td>Pressure </td><td><input type="number" step="any" id="inP"></td><td>Psia</td></tr>

                    <tr><td>Mole Percent H2S </td><td><input type="number" step="any" id="inH2S"></td><td>%mole</td></tr>
                    <tr><td>Mole Percent CO2 </td><td><input type="number" step="any" id="inCO2"></td><td>%mole</td></tr>
                    <tr><td>Mole Percent N2 </td><td><input type="number" step="any" id="inN2"></td><td>%mole</td></tr>
                    <tr><td>Water Salinity </td><td><input type="number" step="any" id="inWS"></td><td>ppm</td></tr>
                </table>
                <br>
                <table>
                    <tr><td><u>Correlation</u></td><td></td></tr>
                    <tr><td>&nbsp</td></tr>
                    <tr>
                        <td>Bubble Point Pressure(Pb) </td>
                        <td>
                            <select id="cor1">
                                <option value="none"></option>
                                <option value="VB">Vasquez and beggs</option>
                                <option value="AM">Al-Marhoun</option>
                                <option value="G">Glaso</option>
                                <option value="PF">Petrosky and Farshad</option>
                                <option value="S">Standing</option>
                            </select>
                        </td>
                    </tr>
                    <tr>
                        <td>Solution GOR(Rs)</td>
                        <td>
                            <select id="cor2">
                                <option value=" "></option>
                                <option value="VB">Vasquez and beggs</option>
                                <option value="AM">Al-Marhoun</option>
                                <option value="G">Glaso</option>
                                <option value="PF">Petrosky and Farshad</option>
                                <option value="S">Standing</option>
                            </select>
                        </td>
                    </tr>
                    <tr>
                        <td>Oil Formation Volume Factor(Bo)  </td>
                        <td>
                            <select id="cor3">
                                <option value=" "></option>
                                <option value="VB">Vasquez and beggs</option>
                                <option value="AM">Al-Marhoun</option>
                                <option value="G">Glaso</option>
                                <option value="PF">Petrosky and Farshad</option>
                                <option value="S">Standing</option>
                            </select>
                        </td>
                    </tr>
                    <tr>
                        <td>Oil Viscosity(µo) </td>
                        <td>
                            <select id="cor4" size="">
                                <option value=" "></option>
                                <option value="CC">Chew Connally</option>
                                <option value="BR">Beggs Robinson</option>
                            </select>
                        </td>
                    </tr>
                    <tr>
                        <td>Water Viscosity(µw) </td>
                        <td>
                            <select id="cor5" size="">
                                <option value=" "></option>
                                <option value="Mc">Mccain</option>
                                <option value="BB">Brill and Beggs</option>
                            </select>
                        </td>
                    </tr>
                </table>
                <br>
                <button type="button" class="conti" onclick="location.href='Out';" >Continue</button><button type="submit" id="cb" class="cal">Calculate</button>
                <button type="button" class="rest" onclick="res()">Reset</button>
                <br>

                <table class="rlt">
                    <tr><td><u>Result</u></td><td></td></tr>

                    <tr><td>Pb</td><td><p id="pb">{{finalpb}}</p></td></tr>
                    <tr><td>Rs(Solution GOR)</td><td><p id="rs"></p></td></tr>
                    <tr><td>Bo</td><td><p id="bo"></p></td></tr>
                    <tr><td>Co</td><td><p id="co"></p></td></tr>
                    <tr><td>µo</td><td><p id="uo"></p></td></tr>
                    <tr><td>ρo</td><td><p id="po"></p></td></tr>
                    <tr><td>Z Factor</td><td><p id="zf"></p></td></tr>
                    <tr><td>Bg</td><td><p id="bg"></p></td></tr>
                    <tr><td>ρg</td><td><p id="pg"></p></td></tr>
                    <tr><td>µg</td><td><p id="ug"></p></td></tr>
                    <tr><td>Bw</td><td><p id="bw"></p></td></tr>
                    <tr><td>µw</td><td><p id="uw"></p></td></tr>
                    <tr><td>ρw</td><td><p id="pw"></p></td></tr>
                    <tr><td>Cw</td><td><p id="cw"></p></td></tr>
                    <tr><td>IFT oil-water</td><td><p id="iow"></p></td></tr>
                    <tr><td>IFT oil-gas</td><td><p id="iog"></p></td></tr>
                </table>
                <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
                <script>

               $('#fm').on('submit',function (e) {
                      $.ajax({
                          type: 'post',
                          url: '/App',
                          data: $('#fm').serialize(),
                          success: function (q) {
                       document.getElementById("pb").innerHTML= q;
                         }
                       });
                     e.preventDefault();
                   });


                </script>

                <br/>
                <footer class="footer">
                <p>Copyright © Invigour Energy 2016</p>
                </footer>
            </form>

        </div>

        </div>
      </div>
  </div>


    <!-- Bootstrap core JavaScript
    ================================================== -->
    <!-- Placed at the end of the document so the pages load faster -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <script>window.jQuery || document.write('<script src="../../assets/js/vendor/jquery.min.js"><\/script>')</script>
    <script src="http://getbootstrap.com/dist/js/bootstrap.min.js"></script>
    <!-- Just to make our placeholder images work. Don't actually copy the next line! -->
    <script src="http://getbootstrap.com/assets/js/vendor/holder.min.js"></script>
    <!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
    <script src="http://getbootstrap.com/assets/js/ie10-viewport-bug-workaround.js"></script>
</body>
</html>

这是我的HTML

请仅查看我的ajax部分

2 个答案:

答案 0 :(得分:0)

更新回复:

让我重新解释一下我的原始答案:不要使用AJAX。这是完全没必要的。删除所有脚本项。我刚刚接受了你的代码,并且在没有任何AJAX的情况下很好地在我的本地烧瓶环境中工作。以下是您需要做的事情:

1)更新你的'按钮',使它们成为输入,输入= submit,并为它们提供所需按钮名称的值(例如,计算)。

2)您的表单输入没有“名称”属性。没有它,表单没有键/值关联。例如,查看您的inOG输入。你需要给它起一个名字......比如name="inOG"

3)我不知道为什么你的C盘作为配置项。也许这是一个Windows的东西?

现在,在调试时,您应该看到表单值很好。

由于以下几个原因,您遇到了问题:

1)你的表格太忙了。理想情况下,根据我的经验,表单应该只包含必要的输入和标签。此外,使用表格格式化html页面通常并不明智。如果您不想完整地编写表单,可以考虑使用Flask-WTF。 Flask的一个好处是能够使用像WTF这样的模板。

2)如果您很好地设置了表单,那么您甚至不需要使用AJAX,这在您的情况下可能更好。提交表单后,您的Flask代码应该完成其余的工作。

2)如果您一直在使用AJAX,那么值得注意的是您的AJAX帖子正好在您的表单代码中间。由于您的浏览器按顺序读取代码,因此它会在表单完成呈现之前选择一个AJAX帖子。您应该将<script>标记插入正文顶部或底部。

3)您正在使用JQuery,这意味着您需要在$(document).ready函数中包装任何可执行代码。因此,如上所述,一旦移动了脚本,就应该编写如下:

<script>

$(document).ready(function(){

$('#fm').on('submit',function (e) {
     $.ajax({
      type: 'post',
      url: '/App',
      data: $('#fm').serialize(),
       success: function (q) {
       document.getElementById("pb").innerHTML= q;
       }
      });
     e.preventDefault();
     });

}

总之,我建议您清理表单并完全取消AJAX。查看您的表单数据,似乎没有什么特别需要脱离正常表单提交。

祝你好运!

答案 1 :(得分:0)

因此在解决了Flask和AJAX中的问题之后,我不会说不使用AJAX。例如,我有一个需要提交的表格,它花了足够长的时间才能生成504。有时需要AJAX。

在必要的情况下,并且您恰巧正在使用Flask(和/或FLASK-WTF),您首先需要更新表单元素以使用新事件。可以通过以下添加来完成。

{{ form.my_element(**{"onchange":"my_ajax_function()"}) }}

将字典作为一个形式传递回Flask表单,并将 onchange 事件设置为使用 my_ajax_function()(如果是按钮,只需将其替换为“ onclick” )

接下来,使用新功能更新您的JavaScript。此功能应执行以下操作:

  1. 获取执行此工作所需的任何字段
  2. 启动ajax请求,并包含url(路由),要发送的数据(如果有)以及对成功/失败请求执行的操作。

这将根据需要更新任何字段,并将数据保留在现有字段中。我会说,如果您避免使用AJAX并让Flask做到这一点,那么生活会容易得多,但这有时是不可避免的。

我还没有尝试过没有响应就返回,而不是使用post请求中的render_template,redirect或make_response来查看字段是否保持原样,但这绝对是可以尝试的东西。

我仅使用AJAX创建动态SelectField,但是关于表单提交有一些有希望的文章,就像FlaskForms不知道如何将这种类型的请求转换回Form对象,因为它们是作为查询发送的参数,因此您需要在字段返回后手动验证它们。 How to submit a Flask-WTF form with Ajax