简体   繁体   English

停止烧瓶复制加载的变量

[英]stop flask duplicating a loaded variable

I'm building a basic cloud infrastructure management site and have a problem with the page that lists virtual machines. 我正在构建一个基本的云基础架构管理站点,并且列出虚拟机的页面有问题。

The flask app pulls a list that is generated via various cloud platform's APIs, and is in the below format: flask应用程序提取通过各种云平台的API生成的列表,格式如下:

vm_list = {
    'vmid': [],
    'name': [],
    'state': [],
    'platform': []
}

the list is populated by looping through the API output and appending each value like so: 通过遍历API输出并附加每个值来填充列表,如下所示:

def zip_list():
    ...
    for node in driver.list_nodes():
        vm_list["vmid"].append(node.uuid)
        vm_list["name"].append(node.name)
        vm_list["state"].append(node.state)
        vm_list["platform"].append(driver.name)
    ...
        myVms = zip(vm_list['name'], vm_list['vmid'], vm_list['platform'], vm_list['state'])
        return myVms

I'm loading this via my flask app like this: 我正在通过我的烧瓶应用程序加载它,如下所示:

@app.route('/vms/')
def vms():
    myVms = {}
    myVms = vm.zip_list()
    return render_template('VMs.html', vm_list=myVms)

The VMs.html page loads this data into a table: VMs.html页面将此数据加载到表中:

<table class="tableClass">
  <tr>
    <th>Name</th>
    <th>id</th>
    <th>Plaform</th>
    <th>State</th>
  </tr>
  {% for row in vm_list %}
  <tr>
    <td>{{ row[0] }}</td>
    <td>{{ row[1] }}</td>
    <td>{{ row[2] }}</td>
    <td>{{ row[3] }}</td>
  <tr>
  {% endfor %}
</table>

And this works fine, loading the data as expected. 并且可以正常工作,按预期加载数据。 However my problem is each time I refresh the page, the data is loaded and appended to the list once again, doubling the table size. 但是,我的问题是每次刷新页面时,数据都会再次加载并追加到列表中,从而使表大小增加了一倍。 Each refresh adds the whole vm_list list to the table once more. 每次刷新将整个vm_list列表再次添加到表中。

I had thought this may be resolved by "nulling" the myVms variable each time it's called (ie myVms = {} ) in the flask app script and/or the zip_list function but that doesn't seem to work; 我以为可以通过在flask应用程序脚本和/或zip_list函数中每次调用myVms变量(即myVms = {} )将myVmsmyVms来解决此问题,但这似乎不起作用。 the issue still persists. 问题仍然存在。

I also looked into flask-caching to see if clearing flask's cache each reload would fix it but it appears not to. 我还查看了烧瓶缓存,以查看每次重新加载时清除烧瓶的缓存是否可以解决该问题,但似乎无法解决。

I'm thinking that I can change something in the html file to force this to only load once per session or something similar, but my front-end skills don't reach out that far. 我在想,我可以更改html文件中的某些内容,以强制每次会话仅加载一次或类似的内容,但是我的前端技能却作用不大。

Does anyone have any idea what I can do in this situation or where I'm going wrong? 有谁知道在这种情况下或在哪里出问题时我能做什么? Any advice is greatly appreciated. 任何意见是极大的赞赏。

You are close - the variable you actually need to reset each time is not myVms but vm_list , as follows: 您很接近-每次实际需要重置的变量不是myVms而是vm_list ,如下所示:

class Node:
    counter = 0

    def __init__(self):
        c_str = str(Node.counter)
        self.uuid = "asdf" + c_str
        self.name = "test " + c_str
        self.state = "wow " + c_str + " such state"
        Node.counter += 1


class Driver:
    def __init__(self, number_of_nodes):
        self.nodes = []
        for x in range(number_of_nodes):
            self.nodes.append(Node())
        self.name = "the greatest driver"

    def list_nodes(self) -> list:
        return self.nodes


driver = Driver(10)


def zip_list():
    vm_list = {'vmid': [], 'name': [], 'state': [], 'platform': []}
    for node in driver.list_nodes():
        vm_list["vmid"].append(node.uuid)
        vm_list["name"].append(node.name)
        vm_list["state"].append(node.state)
        vm_list["platform"].append(driver.name)

    myVms = zip(vm_list['name'], vm_list['vmid'], vm_list['platform'], vm_list['state'])
    return myVms


print("First time:")

my_list = zip_list()
for i in my_list:
    print(i)

print("Second time:")

my_list = zip_list()
for i in my_list:
    print(i)

If you initialise vm_list outside of the zip_list() function instead, you will see the doubling up that you are experiencing. 如果您在zip_list()函数之外初始化vm_list ,则会看到正在经历的翻倍。

You need to initialise vm_list with an empty dict . 您需要使用空dict初始化vm_list And if a key exists, then append to its list, else set the dict[key] with an empty list. 如果存在密钥,则将其追加到列表中,否则将dict[key]设置为空列表。 This is done by setdefault . 这是通过setdefault完成的。

Try this: 尝试这个:

def zip_list():
    ...
    vm_list = {}
    for node in driver.list_nodes():
        vm_list.setdefault('vmid', []).append(node.uuid)
        vm_list.setdefault('name', []).append(node.name)
        vm_list.setdefault('state', []).append(node.state)
        vm_list.setdefault('platform', []).append(node.platform)
    ...
        myVms = zip(vm_list['name'], vm_list['vmid'], vm_list['platform'], vm_list['state'])
        return myVms

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

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