You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 00:18:00