如何在python中从List生成Order List Item

时间:2017-10-10 20:19:33

标签: python list flask jinja2

我尝试从python中的列表创建一个订单列表项(<ol></ol>)。 我的清单如下:

listItem = [    
            ['101','Dashboard'],
            ['102','Potential Customer'],
            ['102-01','Potential Customer Activity'],
            ['102-02','Potential Customer Report'],
            ['102-99','Potentail Customer Detail'],
            ['102-99-01','Potential Customer Detail Listing'],
            ['102-99-02','Potential Customer Follow Up'],
            ['102-99-02-01','Follow Up PAR']
        ]

从此列表中,我希望将其作为itemID的订单列表项,例如101102102-01,...等:

<ol>
    <li data-itemID="101">Dashboard</li>
    <li data-itemID="102">Potential Customer
        <ol>
            <li data-itemID="102-01">Potential Customer Activity</li>
            <li data-itemID="102-99">Potential Customer Detail
                <ol>
                    <li data-itemID="102-99-01">Potential Customer Detail Listing</li>
                    <li data-itemID="102-99-02">Potential Customer Follow Up
                        <ol>
                            <li data-itemID="102-99-02-01">Follow Up PAR</li>
                        </ol>
                    </li>
                </ol>
            </li>
        </ol>
    <li>
<ol>

我已经尝试了以下代码:

from flask import *
import re

app = Flask(__name__)


@app.route('/', methods=['GET','POST'])
def checkName():

    orderList = ''
    listItem = [    
                ['101','Dashboard'],
                ['102','Potential Customer'],
                ['102-01','Potential Customer Activity'],
                ['102-02','Potential Customer Report'],
                ['102-99','Potentail Customer Detail'],
                ['102-99-01','Potential Customer Detail Listing'],
                ['102-99-02','Potential Customer Follow Up'],
                ['102-99-02-01','Follow Up PAR']
            ]
    print "List Item: ",listItem
    orderList += '<ol>'
    for item in listItem:
        if item[0].find('-') > 0:
            # list has sub-list item
            orderList += '<ol>'
            orderList += '<li data-itemID=%s>'%(item[0])
            orderList += item[1]
            orderList += '</li>'
            orderList += '</ol>'
        else:
            # list has no sub-list item
            orderList += '<li data-itemID=%s>'%(item[0])
            orderList += item[1]
            orderList += '</li>'

    orderList += '</ol>'

    return render_template('home.html', orderList=orderList)

if __name__ == '__main__':

    app.run(debug=True)

home.html的

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Home Page</title>
</head>
<body>
    {% if orderList %}
        {{ orderList | safe }}
    {% else %}
        <p>Please select a list menu</p>
    {% endif %}
</body>
</html>

但是,生成的订单列表并不像我上面所期望的那样,它根本没有正确的子订单列表。相反,它的结果如下:

1. Dashboard
2. Potential Customer
   1. Potential Customer Activity
   1. Potential Customer Report
   1. Potentail Customer Detail
   1. Potential Customer Detail Listing
   1. Potential Customer Follow Up
   1. Follow Up PAR

如何更正我的代码以达到上述预期的结果?感谢。

2 个答案:

答案 0 :(得分:1)

此处的代码假定,虽然它遍历listItem,但每次遇到数据ID中带有破折号的项目时,都应启动新的OL。但这不是你想要的。

对于这样的结构,我倾向于使用递归算法来处理子项(这有助于避免像上面那样的假设)。我不知道你的边缘情况,但这样的事情可能适合你:

# somewhere else in your codebase, let's say utils.py

import copy


def structure_listitem(listitem):
    items = copy.deepcopy(listitem)

    if not items:
        return items

    if len(items) == 1:
        items[0].append([])
        return items

    first, rest = items[0], items[1:]

    header = first[0]
    sub_items = []
    while rest and rest[0][0].startswith(header):
        sub_items.append(rest.pop(0))

    first.append(structure_listitem(sub_items))
    return [first] + structure_listitem(rest)


def render_structured_listitem(listitem):
    if not listitem:
        return ''

    out = ['<ol>']
    for item in listitem:
        the_id, header, sublist = item
        if sublist:
            out.append('<li data-itemID="%s">%s\n%s\n</li>'
                       % (the_id, header, render_structured_listitem(sublist)))
        else:
            out.append('<li data-itemID="%s">%s</li>'
                       % (the_id, header))

    out.append('</ol>')
    return '\n'.join(out)


def render_listitem(listitem):
    return render_structured_listitem(structure_listitem(listitem))    

然后,在应用代码中:

from utils import render_listitem # or from wherever

# ...

@app.route('/', methods=['GET','POST'])
def check_name():
    listitem = [    
                ['101','Dashboard'],
                ['102','Potential Customer'],
                ['102-01','Potential Customer Activity'],
                ['102-02','Potential Customer Report'],
                ['102-99','Potentail Customer Detail'],
                ['102-99-01','Potential Customer Detail Listing'],
                ['102-99-02','Potential Customer Follow Up'],
                ['102-99-02-01','Follow Up PAR']
    ]    

    ordered_list = render_listitem(listitem)

    return render_template('home.html', ordered_list=ordered_list)

答案 1 :(得分:0)

如果您不介意使用格式不正确的HTML(我没有关闭<ol>,您可以使用此解决方案。 要获得完全兼容的HTML,需要在同一方向上做一点工作。

flask_file.py

from flask import *
import re

app = Flask(__name__)


itid = lambda x: x[0]
itval = lambda x: x[1]
last = lambda x: x[-1]

def wrapit(it_id):
    return '<li item-id="%s">' % it_id

def wrapval(id_val):
    return '%s</li>' % id_val

def put_ol(it_id):
    return last(it_id.split('-')) == '01'

@app.route('/', methods=['GET','POST'])
def checkName():
    listItem = [
                ['101','Dashboard'],
                ['102','Potential Customer'],
                ['102-01','Potential Customer Activity'],
                ['102-02','Potential Customer Report'],
                ['102-99','Potentail Customer Detail'],
                ['102-99-01','Potential Customer Detail Listing'],
                ['102-99-02','Potential Customer Follow Up'],
                ['102-99-02-01','Follow Up PAR']
            ]
    orderItem = []

    for item in listItem:
        if put_ol(itid(item)):
            orderItem.append('<ol>')
        orderItem.append(wrapit(itid(item)))
        orderItem.append(wrapval(itval(item)))

    print("List Item: %s " % listItem)

    return render_template('home.html', orderItem=orderItem)

if __name__ == '__main__':

    app.run(debug=True)

home.html的

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Home Page</title>
</head>
<body>
<ol>
{% for item in orderItem %}
        {{ item | safe }}
    {% endfor %}
</ol>
</body>
</html>