【问题标题】:Mix Flask/Jinja pagination with refresh of part of page content (div) only (not whole page)混合 Flask/Jinja 分页与仅刷新部分页面内容(div)(不是整个页面)
【发布时间】:2017-09-26 16:52:24
【问题描述】:

到目前为止,我正在使用像 here 中描述的示例那样的 Flask/Jinja 分页(参见页面导航一章)。 这工作正常,但现在由于某些原因我需要在使用分页过程时(即单击下一个/上一个链接时)不重新加载我的(主)页面。我想修改一个 <div>(数据来自通过 SQLAlchemy 的数据库,不确定它是否重要)。

然后我测试了 Ajax 调用以尝试在页面中获取一些动态内容(例如在this example 中)。 这也适用于基本情况(加载 div 等)。

我的问题是,到目前为止,我无法混合使用它们,即flask/Jinja 分页+<div> 的ajax 动态刷新。 我在网上找到了一些很接近的东西,但不完全是这种情况(尤其是涉及 Flask/Jinja)。

我想知道原因是否可能不是第一个示例中的解决方案涉及在单击“下一页/上一页”时对如下路由的新调用 (/index/<int:page>):

@app.route('/', methods=['GET', 'POST'])
@app.route('/index', methods=['GET', 'POST'])
@app.route('/index/<int:page>', methods=['GET', 'POST'])
@login_required
def index(page=1):
    form = PostForm()
    ...

有没有人会:

  • 关于如何处理上述内容的(完整/详细)示例?
  • 或为此的替代解决方案?

顺便说一下,我也测试了 Flask-paginate。不幸的是,它似乎像上面那样重新加载页面。

谢谢。

【问题讨论】:

    标签: jquery python-3.x flask pagination jinja2


    【解决方案1】:

    已经一年多了,所以这对你来说可能没用,但我遇到了同样的问题,下面是我如何解决同样的问题。也许它会帮助某人。

    我将跳过核心 AJAX 部分,仅描述我是如何发现将flask-sqlalchemy 分页与 jquery AJAX 调用混合:

    假设我有一个索引和结果路由的路由。我从模板生成索引页面,然后在表单中添加一个事件以从输入中发布数据,然后使用 jquery AJAX 调用(不是典型的 JSON 文件)获取 html 结果

    现在的问题是:如何将新页面参数传递给调用?

    我想出:通过 url_for 将页码包含为查询字符串,然后 使用 jquery 从页面链接获取 href attr,然后 将其传递给AJAX 调用网址

    代码的关键部分如下所示:

    Jinja/HTML(只负责结果和页面链接生成):

              {% for result in results%}
                    <div>{{ result.name }}</div
              {% endfor %}
    
              {% for page in restaurants.iter_pages() %}
                    <a class="page-link" href="{{ url_for('search_results', page=page) }}">{{ page }}</a>
              {% endfor %}
    

    JQuery 脚本(仅负责从页面链接调用 ajax 的部分):

      $(document).ready(function() {
    
        $(document).on('click', '.page-link', function(event) {
    
          var link = $(this).attr('href');
          searchResults(link);
          event.preventDefault();
    
      });
    });
    
      var searchResults = function(link) {
          req=$.ajax({
            data : {
              parameter1: $('input[name="parameter1"]').val()
            },
            type: 'POST',
            url: link
    
          });
          req.done(function(data) {
            $('#results').html(data);
          })
      };
    

    烧瓶:

    @app.route('/index', methods=['GET', 'POST'])
    def mainPage():
        return render_template("index.html")
    
    @app.route('_search_results', methods=['GET', 'POST'])
    def searchResults():
        page = request.args.get('page')
        page = 1 if page == None else int(page)
        user_parameter = request.form['parameter1'].lower()
        results = Item.query.filter(Item.parameter == user_parameter).paginate(page=page)
    
        return render_template("results.html", results=results)
    

    【讨论】:

      【解决方案2】:

      我已经做了以下来解决这个问题:

      在我的python代码中..
      1. 我正在使用 Pagination.items 提取页面的项目。
      2. 我正在使用 Pagination.iter_pages(..) 提取页码列表 并将两者都作为 json 响应发送。

      @app.route('/filter', defaults={'page_num':1}, methods=['get'])
      @app.route('/filter/<int:page_num>', methods=['get'])
      def filter(page_num):
          if request.method=='GET':
              filter_criteria = request.args.get("query")
      
              if filter_criteria != "":
                  like_filter_criteria = "%" + filter_criteria + "%"
                  search_results = db.session.query(Data).filter(or_(Data.mobile1.like(like_filter_criteria),
                  Data.mobile2.like(like_filter_criteria),
                  Data.mobile3.like(like_filter_criteria))).filter(and_(Data.active_status == "Y")).order_by(Data.name)
              else:
                  search_results = fetch_all_details()
      
              if search_results != None:
                  paginationObj = search_results.paginate(per_page=3,page=page_num,error_out=True)
                  num_list = []
                  for i in paginationObj.iter_pages(left_edge = 3, right_edge = 3, left_current = 3, right_current = 3):
                      num_list.append(i)
                  return jsonify({'json_list' : [i.serialize for i in paginationObj.items],
                  'pages_lst' : num_list})
      
      
      


      在我的 JavaScript..
      1.我正在正常访问要在每个页面上显示的项目的值

          function get_cust_data(pageNum){
            var formData = {'query': $('input[name=query]').val()}
      
              $.ajax({
                  url: '/filter' + pageNum,
                  data: formData,
                  type: 'GET',
                  success: function(response) {
                      console.log(response);
                      show_data_in_table(response);
                  },
                  error: function(error) {
                      console.log(error);
                  }
              });
          }
      
          function show_data_in_table(response){
              var new_tbody = document.createElement('tbody');
              new_tbody.setAttribute("id","tbody");
              var data = response['json_list'];
              var page_numbers = response['pages_lst'];
      
              var cust_data = '';
              $.each(data, function(key, value){
                cust_data += '<tr>';
                cust_data += '<td>' + value.name + '</td>';
                cust_data += '<td>' + value.mobile1 + '</td>';
                cust_data += '<td>' + value.mobile2 + '</td>';
                cust_data += '<td>' + value.mobile3 + '</td>';
                cust_data += '<td>' + value.address + '</td>';
                cust_data += '<td>' + '<a href='+ Flask.url_for('index',{'id':value.id, 'action':'edit'}) +'>Edit</a></td>';
                cust_data += '<td>' +
                '<form id="frm_delete" action="'+ Flask.url_for('delete_cust') +'" method="post" role="form">' +
                  '<input type="hidden" name="id_to_delete" id="id_to_delete" value="'+ value.id + '">' +
                  '<a href="#" id="btn_delete">Delete</a>' +
                '</form>' + '</td>';
                cust_data += '</tr>';
              });
              new_tbody.innerHTML = cust_data;
              var old_tbody = document.getElementById('tbody');
              old_tbody.parentNode.replaceChild(new_tbody, old_tbody);
      
              show_page_numbers(page_numbers);
      
          }
      
      1. 并以同样的方式访问页码列表。
          function show_page_numbers(page_numbers){
            var new_links_box = document.createElement('div');
            new_links_box.setAttribute("id","paginationBox");
      
            var anchorTags = '';
            for (var i = 0; i < page_numbers.length; i++){
              var item = page_numbers[i] === null ? ellipsis : page_numbers[i] ;
              anchorTags += '<a href='+ Flask.url_for('filter') + ' id="page_num_link">'+ item +'</a> &nbsp;&nbsp;&nbsp;';
            }
            new_links_box.innerHTML = anchorTags;
            var old_links_box = document.getElementById('paginationBox');
            old_links_box.parentNode.replaceChild(new_links_box,old_links_box);
          }
      

      然后我使用一些好的旧 js 来访问用户单击的页码并将其发送以与我的 ajax 调用一起使用,该调用也会在页面加载时被调用。

      $("#datalist").on("click","#paginationBox #page_num_link", function(e){
              e.preventDefault();
              var page = '/' + $(e.target).html();
              if(page != ellipsis){
                  get_cust_data(page);
              }
            });
      


      这就是我的模板的样子。它基本上什么都没有,因为一切都是动态的。

                <table id="body_tbl">
                  <thead>
                    <tr>
                      <th>Name</th>
                      <th>mobile 1</th>
                      <th>mobile 2</th>
                      <th>mobile 3</th>
                      <th>Address</th>
                      <th>Edit</th>
                      <th>Delete</th>
                     </tr>
                 </thead>
                 <tbody id="tbody">
                 </tbody>
                </table>
      
                <div id="paginationBox">
                </div>
      

      这样,当分页功能按预期工作时,链接点击事件不会加载页面。 希望这会有所帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-07-27
        • 2016-06-10
        • 2015-06-18
        • 2014-06-24
        • 1970-01-01
        • 2020-12-03
        相关资源
        最近更新 更多