我想创建一个导出按钮,以便在搜索完成后,导出函数可以将搜索结果导出为 csv 文件并将此 csv 文件下载到本地计算机。我想到两个想法,但我不知道哪一个在 CKAN 中更好?
- 给出一个 URL,以便该 URL 将接收带有
search_criteria
的请求并首先返回 json 列表,然后将 json 转换为 csv 并下载。在模板文件中,我只需要给出一个像<a href="{{h.url_for(request url)}}">Export</a>
这样的 URL,但我必须在plugin.py
、controller.py
和helpers.py
中实现请求的句柄。 - 提供一个处理请求、转换和下载的 URL,但在模板文件上,我会将"导出"按钮链接到请求 js 文件,如
<a href="request.js">Export</a>
.
对于这两个想法,我必须在路由映射中添加这个新 url,并在控制器和插件中添加响应、转换和下载。我想知道哪个想法需要较少的修改?
1对我来说似乎是一个不错的选择 - 你需要使用一些现有的python代码,所以javascript将是更难的选择。
搜索结果由 search(( 方法中的包控制器(来自 CKAN 2.9 的数据集视图(生成。它接受查询字符串,将一些转换为包含搜索参数(例如 SOLR q 和 fq 参数(的data_dict。 使用这些参数调用package_search
逻辑函数,并以 JSON 列表的形式返回搜索结果列表。现在在控制器中,在呈现模板网页时使用 JSON,但在您的情况下,您希望将其转换为 CSV 并返回它。因此,您可以将控制器 search(( 代码(直到渲染(复制并粘贴到您自己的 CKAN 扩展中,序列化为您需要的内容并返回它。
或者更好的是,您可以为每个人提供解决方案。在 search(( 旁边添加一个控制器方法,并将搜索方法所需的代码分解到它们都调用的单独方法中。将其作为链接添加到模板底部,并将其作为 PR 提交。 :)
我选择了第一种方法,它工作正常,与第二种方法相比,它节省了我的修改以实现export.js
您可以在 url 中添加任何搜索条件,template/search.html
:
<a href={{h.url_for("/export", search_criteria='random string', ...)}}></a>
然后在plugin.py
中,您可以在IRoutes
推理中覆盖before_map
并在before_map
中添加 URL:
class ExportPlugin(plugins.SingletonPlugin):
plugins.implements(plugins.IRoutes, inherit=True)
def before_map(self, m):
m.connect('export', '/export',
controller='ckanext.my_export_plugin.controller:ExportController',
action='export')
然后,在controller.py
中,您可以继承BaseController
以便可以通过package_search
API 处理搜索,并在分面查询fq
中传递任何自定义搜索条件。您还可以在此控制器中添加转换和下载功能:
class ExportController(base.BaseController):
def json_to_csv(original_json):
'''
Other Implementation of convertion
'''
return csv.read()
def export(self, data):
'''
Other Implementation of handling search operation
'''
search_results = toolkit.get_action('package_search')(data_dict=data)
file_name = "export.csv"
response.headers['Content-Type'] = 'application/csv'
response.headers['Content-Disposition'] = file_name
return json_to_csv(search_results)
完成自己的实现后,您应该能够为 REST 服务创建自定义 url,并在后端完全处理请求。