CKAN2.9 数据集(package)表单添加上传字段后无法保存到Filestore求助
第一步:修正模板上传字段配置
你之前的模板里form.image_upload的参数绑定错了字段,要把上传相关的字段名对应到自定义thumbnail字段,否则表单提交时不会把文件流传递到后端:
{% ckan_extends %} {% block package_basic_fields_custom %} {% block basic_fields_thumbnail %} {% set is_upload = data.thumbnail_upload is not none %} {{ form.image_upload(data, errors, field_url='thumbnail', field_upload='thumbnail_upload', field_clear='clear_thumbnail_upload', is_upload_enabled=h.uploads_enabled(), is_url=data.thumbnail and not is_upload, is_upload=is_upload, upload_label=_('Thumbnail'), url_label=_('Thumbnail'), placeholder=_('http://thumbnail.png')) }} {% endblock %} {% endblock %}
第二步:修改schema接收上传参数
你之前的schema只定义了thumbnail字段,需要新增上传相关的临时字段的验证规则,避免上传的文件流被过滤:
def _modify_package_schema(self, schema): schema.update({ 'thumbnail': [toolkit.get_validator('ignore_missing'), toolkit.get_converter('convert_to_extras')], # 添加上传相关字段的验证规则 'thumbnail_upload': [toolkit.get_validator('ignore_missing')], 'clear_thumbnail_upload': [toolkit.get_validator('ignore_missing')] }) return schema
第三步:添加IPackageController钩子处理文件上传
在你的插件类里实现IPackageController接口,在数据集创建/更新后处理上传的文件,直接调用CKAN内置的上传工具存储到Filestore,不需要自己调用外部API:
import ckan.lib.uploader as uploader from ckan.plugins import implements, interfaces class CardThemePlugin(plugins.SingletonPlugin): implements(interfaces.IPackageController, inherit=True) # 数据集创建后处理 def after_create(self, context, pkg_dict): self._handle_thumbnail_upload(context, pkg_dict) return pkg_dict # 数据集更新后处理 def after_update(self, context, pkg_dict): self._handle_thumbnail_upload(context, pkg_dict) return pkg_dict def _handle_thumbnail_upload(self, context, pkg_dict): # 从请求中获取上传的文件 upload = context['request'].params.get('thumbnail_upload') if not upload or hasattr(upload, 'filename') is False: return # 初始化CKAN上传工具,指定存储分组为dataset-thumbnail避免和其他上传文件冲突 upload_obj = uploader.Uploader('dataset-thumbnail', pkg_dict['id']) upload_obj.update_data_dict(pkg_dict, 'thumbnail', upload) # 执行文件存储 upload_obj.upload() # 更新数据集的thumbnail字段为存储后的URL toolkit.get_action('package_patch')( context, {'id': pkg_dict['id'], 'thumbnail': upload_obj.url} )
额外注意点
- 确认Filestore的存储路径有读写权限,配置项
ckan.storage_path指向的目录存在且可被CKAN进程写入 - 如果需要清理旧的缩略图,可以在
_handle_thumbnail_upload方法里先判断旧的thumbnail是否存在,调用upload_obj.delete()删除旧文件
内容的提问来源于stack exchange,提问作者Briana
相关产品推荐
相关产品推荐

