我正在尝试设计一个插件系统来填充网页的不同组件,其中每个插件负责其自己的基础数据 View 或可视化(可能是股票数据,例如 1000 只股票)。 我需要帮助想出一个简单但正确分离 MVC 组件的设计。我觉得我当前的设计在整个 html 中不当混合,并且很难更改主 index.html 页面的整体布局。 我不确定如何解决这个问题,同时保持代码简单和轻量级,同时允许每个插件在其放置在页面部分的内容方面具有最大的灵 active 。 执行此操作的最佳实践想法/库是什么?
我的一个想法是生成由预定义的 javascript/html 小部件使用的 json。 是否有 python 库为此提供架构(也许还有一些不错的数据显示小部件)?
为了提供一些背景信息,这些插件将成为应用程序的一部分,该应用程序为科学家提供了一种简单的基于网络的方式来查看数据分析管道的结果。 该管道生成 1 到 1000 个目录(每个实验样本一个),每个目录包含 5 到 20 个标准和自定义文件类型。我的 python 应用程序抓取这些目录并生成一个网页,可以在其中查看所有样本的每种类型的结果(以某种摘要格式,或通过翻转/滚动样本)。
[1] http://effbot.org/zone/metaclass-plugins.htm
谢谢 -本
附言。我当前的伪代码是:
plugin_registry = []
class FileTypeHandlerPlugin:
__metaclass__ = register_plugin # based on effbot.org post [1]
# Base class's methods won't contain code. Just included for explanation.
def handle_files(self, all_file_paths):
# 1. pick out the files of your type
# 2. parse the files and create data structure to use by get_html(..)
# 3. maybe generate some files and summary graphs (eg. summary_graph.png)
def get_html(self):
# get the html
result = """
<img src="summary_graph.png">
<table>
<tr><td>sample</td><td>value1</td><td>value2...
<tr><td>s1 ...
</table>
"""
return result
def get_heading(self):
return "some heading"
class FileType1Handler(FileTypeHandlerPlugin):
def get_html(self)
return "<pre>%s</pre>" % self.quality_string....
def get_heading(self):
return "Quality Scores"
def handle_files(self, all_file_paths):
self.quality_score_files = [p for p in all_file_paths if p.endswith(".qual")]
...
def main():
all_file_paths = []
for dirpath, dirnames, filenames in os.walk("."):
all_file_paths.extend(filenames)
for plugin in plugin_registry:
plugin.handle_files(all_file_paths)
f = open("index.html", "w")
for plugin in plugin_registry:
f.write( "<h3>" + plugin.get_heading() + "</h3>")
f.write( plugin.get_html() )
f.close()
webserver.start()
请您参考如下方法:
也许它有助于在经典中看到这一点 MVC范式。
- 您的模型应该从文件中检索数据。
- 您的 View 应该以他们认为合适的方式装饰数据
- 您的 Controller 应该将 View 与正确的模型联系起来并处理用户输入等内容。
在这种情况下,这意味着您的插件主要是 View 插件,它们将通过 Controller 注册自己。
在您当前的代码中,尤其是 View 和 Controller 似乎有点交织在一起。我会做类似这样的伪代码(使用更清晰的模块和内容布局):
class CSVHandler():
# A view plugin, which can output HTML.
def handle(data):
output = ''
for file in data:
if data.type != 'csv':
continue
# Do stuff into output
return output
view_plugins = []
def register_view_plugin(plugin):
view_plugins.append(plugin)
register_view_plugin(SummaryHandler())
register_view_plugin(CSVHandler())
register_view_plugin(PDFHandler())
def render(data):
output = '\n'.join([x.handle(data) for x in view_plugins])
@app.route('/show/<sample_id>')
def show(sample_id):
# This is the controller
data = get_data(sample_id)
return render(data)
def get_data(sample_id):
# Return a model of the data.
return [{'type': 'csv', 'content': '...'},
{'type': 'pdf', 'author': 'Foo', 'content': '...'}]
