停止烧瓶复制加载的变量
stop flask duplicating a loaded variable
我正在构建一个基本的云基础架构管理站点,但是列出虚拟机的页面有问题。
flask 应用程序拉取通过各种云平台的 APIs 生成的列表,格式如下:
vm_list = {
'vmid': [],
'name': [],
'state': [],
'platform': []
}
通过遍历 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
我正在通过我的烧瓶应用加载这个:
@app.route('/vms/')
def vms():
myVms = {}
myVms = vm.zip_list()
return render_template('VMs.html', vm_list=myVms)
VMs.html
页面将此数据加载到 table:
<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>
这工作正常,按预期加载数据。但是我的问题是每次刷新页面时,数据都会再次加载并附加到列表中,使 table 大小加倍。每次刷新都会将整个 vm_list
列表再次添加到 table 中。
我原以为这可以通过 "nulling" 每次在烧瓶应用程序脚本中调用 myVms
变量(即 myVms = {}
)来解决 and/or zip_list
功能,但这似乎不起作用;问题仍然存在。
我还调查了 flask-caching 以查看每次重新加载时清除 Flask 的缓存是否可以修复它,但似乎不能。
我想我可以更改 html 文件中的某些内容以强制它在每个会话或类似的东西中只加载一次,但我的前端技能并没有达到那么远。
有没有人知道我在这种情况下可以做什么或哪里出错了?非常感谢任何建议。
你很接近——你每次实际需要重新设置的变量不是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)
如果您在 zip_list()
函数之外初始化 vm_list
,您将看到您正在经历的加倍。
您需要使用空 dict
初始化 vm_list
。如果一个键存在,则附加到它的列表,否则将 dict[key]
设置为空列表。这是由 setdefault
.
完成的
试试这个:
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
我正在构建一个基本的云基础架构管理站点,但是列出虚拟机的页面有问题。
flask 应用程序拉取通过各种云平台的 APIs 生成的列表,格式如下:
vm_list = {
'vmid': [],
'name': [],
'state': [],
'platform': []
}
通过遍历 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
我正在通过我的烧瓶应用加载这个:
@app.route('/vms/')
def vms():
myVms = {}
myVms = vm.zip_list()
return render_template('VMs.html', vm_list=myVms)
VMs.html
页面将此数据加载到 table:
<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>
这工作正常,按预期加载数据。但是我的问题是每次刷新页面时,数据都会再次加载并附加到列表中,使 table 大小加倍。每次刷新都会将整个 vm_list
列表再次添加到 table 中。
我原以为这可以通过 "nulling" 每次在烧瓶应用程序脚本中调用 myVms
变量(即 myVms = {}
)来解决 and/or zip_list
功能,但这似乎不起作用;问题仍然存在。
我还调查了 flask-caching 以查看每次重新加载时清除 Flask 的缓存是否可以修复它,但似乎不能。
我想我可以更改 html 文件中的某些内容以强制它在每个会话或类似的东西中只加载一次,但我的前端技能并没有达到那么远。
有没有人知道我在这种情况下可以做什么或哪里出错了?非常感谢任何建议。
你很接近——你每次实际需要重新设置的变量不是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)
如果您在 zip_list()
函数之外初始化 vm_list
,您将看到您正在经历的加倍。
您需要使用空 dict
初始化 vm_list
。如果一个键存在,则附加到它的列表,否则将 dict[key]
设置为空列表。这是由 setdefault
.
试试这个:
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