【问题标题】:Paginate through json data with Flask使用 Flask 对 json 数据进行分页
【发布时间】:2018-06-25 17:42:40
【问题描述】:

我正在使用烧瓶并生成填充了我检索到的 JSON 数据的表。我现在遇到的问题是我需要对所有 JSON 数据进行分页,因为每页的最大值设置为“50”,并且我想显示表中的所有产品。

到目前为止,我无法让它工作,我真的不知道如何让它与 Flask 一起工作。我尝试使用 while 循环,但这不适用于 Jinja2,因为该命令无法识别。

这是我的 Python 代码:

@app.route('/products',methods = ['POST', 'GET'])
def products():
    shopnaam = request.form['shopname'] 
    username = request.form['username']
    password = request.form['password']
    login = 'https://'+shopnaam+'example.com'
    url = 'https://'+shopnaam+'.example.com/admin/products.json'

    payload = {
          'login[email]': username,
          'login[password]': password
          }

    with requests.Session() as session:
          post = session.post(login, data=payload)

          r = session.get(url)
          parsed = json.loads(r.text)


    return render_template('producten.html',parsed = parsed)

这是我的 Jinja2 代码:

<button class="collapsible">Bekijk product Informatie</button>
<div class="content">
<table id = "productentabel">
  <tr class = "header">
    <th>ID</th>
    <th>Titel </th>
    <th>Prijs Exclusief BTW</th>
    <th>Prijs Inclusief BTW</th>
    <th>Datum</th>

    {% for product in parsed['products'] %}
    <TR>
    <TD  width="100px" >{{product['id']}}</TD>
    <TD  width="300px" >{{product['nl']['title']}}</TD>
    <TD  width="150px">{{product['price_excl']}}</TD>
    <TD  width="150px">{{product['price_incl']}}</TD>
    <TD  width="300px">{{product['created_at']}}</TD>
    </TR>
    </tr>
    {% endfor %}
    </table>

<input class = "exportknop" value="Exporteer product informatie" type="button" onclick="$('#productentabel').table2CSV({header:['ID','Titel','Prijs Exclusief BTW', 'Prijs Inclusief BTW', 'Datum']})">     
</div>

如您所见,我使用的是 for 循环,这段代码可以工作,但分页是个问题。

我的 JSON 如下所示:

products: [
{
article_code: "123",
barcode: "456",
brand_id: 2600822,
created_at: "2018-05-31T15:15:34+02:00",
data01: "",
data02: "",
data03: "",
delivery_date_id: null,
has_custom_fields: false,
has_discounts: false,
has_matrix: false,
hits: 0,
hs_code: null,
id: 72660113,
image_id: null,
is_visible: false,
price_excl: 33.0165,
price_incl: 39.95,
price_old_excl: 0,
price_old_incl: 0,
product_set_id: null,
product_type_id: null,
search_context: "123 456 789",
shop_id: 252449,
sku: "789",
supplier_id: 555236,
updated_at: "2018-05-31T15:15:34+02:00",
variants_count: 1,
visibility: "hidden",
weight: 0,

links: {
first: ".json",
last: ".json?page=70",
prev: null,
next: ".json?page=2",
count: 3497,
limit: 50,
pages: 70
}

所以链接是分页发生的地方,我在我的 Python 代码中尝试了以下内容,这样我得到了在我的 python 终端中打印的所有值。只有我不能将数据发送到表中。

while url:
        with requests.Session() as session:
            post = session.post(login, data=payload)
            r = session.get(url)
            parsed = json.loads(r.text)
            for product in parsed['products']:
                print(product['id'], product['nl']['title'])
            url = 'https://example/admin/products' + parsed['links']['next']  

【问题讨论】:

    标签: python json api flask jinja2


    【解决方案1】:

    这里有几件事需要考虑。首先,在 websocket 或异步调用之外,使用生成器创建 Web 内容几乎是不可能的。原因是 WSGI 在渲染之前需要所有数据。然后它关闭连接。您可以生成数据,但在表格中,这将导致原始 html 出现问题。

    做什么:

    我会使用类似 datatables (datatables.net) 的东西将您的表格数据输入到一个变量中,并让 datatables 为您处理分页。

    使用 Bootstrap 4 和 DataTables 的示例。

    <script>
    var dataSet = []
    var wurl = ""
    
    tablex = $('#tablex').dataTable( {
        select: true,
        stateSave: true,
        colReorder: true,
        deferRender: true,
        "oLanguage": {"sSearch": "Filter:"},
        columns: [
            { title: "Number" },
            { title: "Client Name" },
            { title: "Opened" },
            { title: "Closed" },
            { title: "Worked" }
        ]
    } );
    
    function generate() {
    $.get(wurl, function( data ) {
      dataSet = data;
      tablex.fnDestroy();
      tablex = $('#tablex').dataTable( {
        data: dataSet,
        select: true,
        stateSave: true,
        colReorder: true,
        deferRender: true,
        "oLanguage": {"sSearch": "Filter:"},
        columns: [
            { title: "Number" },
            { title: "Client Name" },
            { title: "Opened"},
            { title: "Closed"},
            { title: "Worked"}
        ],
    } );
    });
    };
    
    $(document).ready(function() {
    wurl = '/api/getdata';
    generate()
    } );
    
    </script>
    

    我首先只建立一个基表,然后调用 API 并在后台加载该表和数据。如果需要,您甚至可以进行此轮询并定期刷新数据集。 API 只是在列输出中提供原始数据。

    在本例中,您的表 ID 为“tablex”。
    您的 API 路由可以是任何东西,只是以列和行格式的输出的返回值。

    【讨论】:

    • 嗨@eatmeiamdanish 感谢您的回答。所以我必须从 python 发送到这个脚本的唯一值是 url?还是别的什么?
    • 这是一个通用示例。显然你会用你自己的名字设置你的列。但是......您所要做的就是拥有 api,在这种情况下,'/api/getdata' 返回一个 json 列表列表,这意味着您将在列表中返回您的行。数据表将完成其余的分页。
    • Datatables 也提供了它自己的服务器端分页,但这变得复杂了。为页面按下的每个按钮都会向查询发送一个偏移量和一个限制,但是如果您进行过滤,这会发生变化,因此您也必须考虑到这一点。为简单起见,如果您的行数少于 100k,请使用启用延迟的客户端。
    • 我已经感觉到这会变得有点太复杂了。因此,我采用了另一种解决方案,首先将数据推送到数据库,然后再检索它。感谢您推荐Datatables,我现在正在使用它:)
    • 如果您需要任何其他可能对您有所帮助的代码,请随时私下与我联系。我有大量经过时间考验的工具可以缩短复杂性。
    猜你喜欢
    • 2011-01-31
    • 1970-01-01
    • 2014-12-26
    • 2016-04-14
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    • 2016-03-29
    • 2018-11-29
    相关资源
    最近更新 更多