Flask:渲染模板和填充HTML表

时间:2016-11-21 23:08:01

标签: python python-3.x flask datatables flask-sqlalchemy

让我解释一下我的最终目标,然后这可能会描绘出我想要做的事情。以下是我的应用程序需要做的事情:

  1. 最终用户转到http://www.example.com/ms_bulletins,他们会看到一个带有可选日期的下拉菜单。
  2. 一旦他们选择了日期,就会将日期发送到我的烧瓶后端,日期用于查询数据库中该公告的日期。
  3. 然后公告应该返回http://www.example.com/ms_bulletins,表格应该填充。
  4. 我实际上几乎完全没有这个工作,除了页面没有加载显示数据。以下是一些代码片段:

    的JavaScript

    function dateClick(date){
      var dropdown = document.getElementById("date");
      var date = dropdown.options[dropdown.selectedIndex].value;
      console.log( "Date: " + date );
      $.getJSON($SCRIPT_ROOT + '/ms_bulletins', {
                date: date,
      });
    }
    

    烧瓶

    @application.route("/ms_bulletins")
    def ms_bulletins():
        date = request.args.get('date', None, type=str)
        session = Session()
        data = session.query(MsBulletins).filter(MsBulletins.date==date)
        bulletins = data.all()
        return render_template("ms_bulletins.html", bulletins=bulletins)
    

    HTML

    <script>
    $(document).ready( function () {
       $('#bulletin_table').DataTable();
    } );
    </script>
    
    <div id="select_bulletin_date" onchange="dateClick(this)">
    <form>
      <fieldset>
      <legend class="header">MS Bulletin Summary:</legend>
      <select id="date">
        <option name="date" value="11/8/2016">November 2016</option>
        <option name="date" value="10/11/2016">October 2016</option>
      </select>
      </fieldset>
    </form>
    </div>
    <hr>
    <div id="ms_bulletins">
    <table id="bulletin_table" class="display">
    <thead>
        <tr>
            <th>Bulletin ID</th>
            <th>Bulletin KB</th>
            <th>Bulletin Name</th>
            <th>Bulletin Date</th>
        </tr>
    </thead>
    <tbody>
      {% for bulletin in bulletins %}
        <tr>
            <td><a href="https://technet.microsoft.com/en-us/library/security/{{ bulletin.bulletin_id }}" target="_blank">{{ bulletin.bulletin_id }}</a></td>
            <td><a href="https://support.microsoft.com/en-us/kb/{{ bulletin.kb }}" target="_blank">{{ bulletin.kb }}</a></td>
            <td>{{ bulletin.title }}</td>
            <td>{{ bulletin.date }}</td>
        </tr>
      {% endfor %}
    </tbody>
    </table>
    </div>
    

    目前,当用户转到http://www.example.com/ms_bulletins时,表格为空白,然后用户选择日期,我可以看到控制台中传递的日期,然后没有任何反应。

    如果我在&#34;渲染模板&#34;之后查看源代码。应该已经发生了,我可以在源代码中看到它确实有效:

    源代码

    <table id="bulletin_table" class="display">
      <thead>
        <tr>
          <th>Bulletin ID</th>
          <th>Bulletin KB</th>
          <th>Bulletin Name</th>
          <th>Bulletin Date</th>
       </tr>
      </thead>
    <tbody>
       <tr>
        <td><a href="https://technet.microsoft.com/en-us/library/security/MS16-142" target="_blank">MS16-142</a></td>
        <td><a href="https://support.microsoft.com/en-us/kb/3198467" target="_blank">3198467</a></td>
        <td>Cumulative Security Update for Internet Explorer</td>
        <td>11/8/2016</td>
      </tr>
      <tr>
        <td><a href="https://technet.microsoft.com/en-us/library/security/MS16-141" target="_blank">MS16-141</a></td>
        <td><a href="https://support.microsoft.com/en-us/kb/3202790" target="_blank">3202790</a></td>
        <td>Security Update for Adobe Flash Player</td>
        <td>11/8/2016</td>
     </tr>
    </tbody>
    </table>
    

    但是,页面本身从不加载此数据。

    我甚至可以做到什么?如果是这样,我在这里失去的步骤是什么?

1 个答案:

答案 0 :(得分:2)

基于上述信息,我认为您需要:

  1. 将实际表单数据提交给Flask后端,或
  2. 修改您的异步调用以修改实际的DOM表
  3. 目前您的$ .getJSON调用正在调用Flask函数,但您没有包含更新实际HTML页面的方法。它只是将一组HTML返回给浏览器,但没有告诉浏览器对它做任何事情。服务器端脚本将在GET或POST请求上运行,但通过XHR发出此请求不会告诉您的浏览器刷新。 JQuery $ .getJSON()调用是一种从Flask后端异步获取数据的方法,但是要使用此功能,您还需要在Javascript中处理生成的DOM操作(例如,在没有页面重新加载的情况下执行此操作)。

    DataTables是一个很棒的工具。我将在前两个场景中忽略它并解释你将如何在我的第三个场景中实现它。

    所以,我认为你有3个选择:

    1)您是否已将数据POST到Flask应用程序,在这种情况下,您需要更改视图功能以接受GET和POST响应:

    <form method="POST" action="">
    

    将表单操作更改为

    from Flask import jsonify
    
    @application.route("/_get_bulletins")
    def _get_bulletins():
        date = request.args.get('date', None, type=str)
        session = Session()
        data = session.query(MsBulletins).filter(MsBulletins.date==date)
        bulletins = data.all()
        return jsonify(bulletins)
    

    然后完全删除Javascript函数。这应该有效,页面将在每次调用时重新加载。

    2)要进入异步路由,需要添加第二个Flask功能:

    function dateClick(date){
        var dropdown = document.getElementById("date");
        var date = dropdown.options[dropdown.selectedIndex].value;
        var table = $('#bulletin_table').find('tbody');
        table.empty();
        console.log( "Date: " + date );
        $.getJSON('{{ url_for('._get_bulletins') }}', date, 
            function (data ){
                console.log(data);
                for (var x = 0; x < data.length; x++) {
                    var row = $('<tr>');
                    row.append($('<td>').text(data[x][0]));
                    row.append($('<td>').text(data[x][1]));
                    table.append(row);
                }
        });
    }
    

    然后,修改您的javascript函数以将结果合并到DOM中:

    var dt = $('#bulletin_table').DataTable();
    

    3)转到Async路由并使用DataTables。要使用它,我建议将更详细的配置传递给DataTables API。它有很好的记录和功能。实现这一目标的核心功能是。

    将DataTable引用存储在变量中。

    function dateClick(date){
        var dropdown = document.getElementById("date");
        var date = dropdown.options[dropdown.selectedIndex].value;
        console.log( "Date: " + date );
        $.getJSON('{{ url_for('._get_bulletins') }}', date, 
            function (data ){
                console.log(data);
                dt.empty();
                dt.rows.add(data).draw();
        });
    }
    

    更改您的javascript函数以操作DataTable,而不是DOM:

    CREATE TYPE [udtCustom] FROM [nvarchar](7) NULL
    
相关问题