繁体   English   中英

使用 Flask、jinja2、python 和 js 动态加载 html 表

[英]Load html table with Flask, jinja2, python and js dynamically

我使用 Flask 创建了一个测试网站,该网站显示来自 postgres 数据库的数据,按类别、产品、月份和日期排序。 每个类别下的所有表格行都被隐藏。 单击一行将展开/折叠其下方的 1 级行。 因此,单击一个类别将显示所有产品。 单击产品将显示所有月份的数据。

目前,正如您在代码中看到的,加载页面时会检索所有记录。

测试网站是显示数千条记录的网站的简化版。 我想将该网站用于具有数百万条记录的不同数据库。

不幸的是,页面加载和展开/折叠需要很长时间。 我不想在单击时折叠/展开行,而是在每次展开类别、产品或月份时使用 Flask 查询数据库,并向表中添加 1 级行,其中包含查询返回的数据。

这可以用 Flask、jinja2 和 js 来完成吗?

带有jinja2代码的html模板

<!DOCTYPE html>
<html>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script type=text/javascript src="{{url_for('static', filename='js/test.js') }}"></script>
    <link rel= "stylesheet" type= "text/css" href= "{{ url_for('static',filename='styles/test.css') }}">
    <title>Test Table</title>
    <body>
        <table class = "products">
            <thead>
                <tr>
                    <th>Product</th>
                    <th>Month</th>
                    <th>Date</th>
                </tr>
            </thead>
            <tbody>
                {% for category in types %}
                    <tr class="category" data-level="0" vis_id = "{{ category.category}}">
                        <td colspan = 3 class="nosides">
                        <label>{{ category.category}}</label>
                        </td
                    </tr>
                    {% for product in category.products %}
                        <tr class="parent" data-level="1" vis_id = "{{ product.product }}" par_vis_id = "{{ category.category}}">
                            <td colspan = 3 class="nosides">
                            <label>{{ product.product }}</label>
                            </td>
                        </tr>
                        {% for month in product.months %}
                            <tr class="parent" data-level="2" vis_id = "{{ product.product }}_{{ month.month }}" par_vis_id = "{{ product.product }}">
                                <td colspan=1 class="noright"></td>
                                <td colspan=2 class="nosides">
                                <label>{{ month.month }}</label>
                                </td>
                            </tr>
                            {% for date in month.date %}
                                <tr class="child" data-level="3" vis_id = "{{ date.date }}" par_vis_id = "{{ product.product }}_{{ month.month }}">
                                    <td colspan = 2></td>
                                    <td>{{ date.date }}</td>
                                </tr>
                            {% endfor %}
                        {% endfor %}
                    {% endfor %}
                {% endfor %}
            </tbody>
        </table>
    </body>
</html>

Python烧瓶代码

import sys, os
from flask import Flask, render_template
import pandas as pd
import pandas.io.sql as psql

@app.route('/test_table')
def test_table():
    con = set_con('db')
    sys_list = []
    #select all the records
    df = pd.read_sql("select category, product, TO_CHAR(date, 'Mon YYYY') as month, TO_CHAR(date, 'YYYY-MM-DD HH24:MI:SS') as date \
        from db  order by category, product, date desc", con)
    query = "Select distinct product from db order by product"
    #get a list of categories, products and months, then loop over each.
    df_products = pd.read_sql(query, con)
    query = "Select distinct category from products"
    df_sys = pd.read_sql(query,con)
    for category in df_sys['category'].values:
        products_list = []
        df_sys_tmp = df[df['category']==category]
        if df_sys_tmp.empty:
            continue
        for product in df_products['product'].values:
            df_product_tmp = df_sys_tmp[df_sys_tmp['product']==product]
            if df_product_tmp.empty:
                continue
            months = df_product_tmp['month'].unique()
            tmp_list_months = []
            for month in months:
                 #loop over all the records for this particular category, product, and month.
                df_recs = df_product_tmp[df_product_tmp['month']==month]
                if df_recs.empty:
                    continue
                tmp_list_recs = []
                for i, row in df_recs.iterrows():
            
                    tmp_list_recs.append({'date':row['date']})
                tmp_list_months.append({'month':month, 'date':tmp_list_recs})
            
            products_list.append({'product':product, 'months':tmp_list_months})
        sys_list.append({'category':category, 'products':products_list})
    return render_template(test.html',types=sys_list)
if __name__ == '__main__':
    main()

js


function toggleIf(element, condition) {
    if (condition ===true || condition === 'true') { element.show(); }
    else { element.hide(); }
};
$(document).ready(function() {

    function getChildren($row) {
        var children = [], level = $row.attr('data-level');
        while($row.next().attr('data-level') > level) {
             children.push($row.next());
             $row = $row.next();
        };
        return children.sort((a, b) => parseFloat(a.attr('data-level')) - parseFloat(b.attr('data-level')));;
    };

    $('.parent').on('click', function() {
        var children = getChildren($(this));
        var datalevel = $(this).attr('data-level')
        var vis_id = $(this).attr('vis_id')
        $.each(children, function() {
            par_vis_id = $(this).attr('par_vis_id')
            if (datalevel==1){
              if ($(this).attr('data-level')==2){
                $(this).toggle();}
              else{
                if ($(this).is(":visible")){
                    $(this).toggle();}}}
             else{$(this).toggle();}
        sessvisible = $(this).is(":visible")

    if (sessvisible) {
       sessionStorage.setItem(par_vis_id, 'true')
    }
    else{
       try {
             sessionStorage.removeItem(par_vis_id);}
        catch { };};});
    });
    $('.product').on('click', function() {
    var children = getChildren($(this));
    var vis_id = $(this).attr('vis_id')

    $.each(children, function() {
          item_visible = $(this).is(":visible")
          if ($(this).attr('data-level')==1){
            $(this).toggle();
            product_visible = $(this).is(":visible")
            if (!product_visible) {
              try {
             sessionStorage.removeItem($(this).attr('vis_id'));}
             catch { };}}          else{
            if (item_visible){
                $(this).toggle();}
                try {
                    sessionStorage.removeItem($(this).attr('vis_id'));}
                catch { };
          }})
    if (product_visible) {
       sessionStorage.setItem(vis_id, 'true')
    }
    else{
       try {
             sessionStorage.removeItem(vis_id);}
        catch { };};
         });

    $('.parent').on('custom', function() {
        var children = getChildren($(this));
        var datalevel = $(this).attr('data-level')
        var vis_id = $(this).attr('vis_id')
        $.each(children, function() {
            if (datalevel==1){
              if ($(this).attr('data-level')==2){
                $(this).toggle();}
              else{
                if ($(this).is(":visible")){
                    $(this).toggle();}}}
             else{$(this).toggle();}
        });
    });

    $('.product').on('custom', function() {
    var children = getChildren($(this));
    var vis_id = $(this).attr('vis_id')

    $.each(children, function() {
          item_visible = $(this).is(":visible")
          if ($(this).attr('data-level')==1){
            $(this).toggle();}
          else{
            if (item_visible){
          $(this).toggle();}}
         });
     });

    $('.product').each(function(i, tr) {
        var isvisible = $(this).is(":visible")
        var children = getChildren($(this));
        var vis_id = $(this).attr('vis_id')
        if (sessionStorage.getItem(vis_id) !== null){
          $(this).trigger('custom');
        }
        $.each(children, function() {
            var datalevel = $(this).attr('data-level')
            if (datalevel !== '3'){
                var vis_id = $(this).attr('vis_id')
                if (sessionStorage.getItem(vis_id) !== null){
                    $(this).trigger('custom');};};
        });
    });
});

我能够使用 XMLHTTPRequests 和 Flask 和 JS 来做到这一点。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM