如何为CKAN数据记录表单添加更多可见性选项?
修改CKAN数据集可见性选项的实现方案
1. 前端模板修改(package_basic_fields.html)
找到原有可见性选择器的代码块,替换为包含新选项的下拉框:
<select id="field-visibility" name="visibility" class="form-control"> <option value="public" {% if data.visibility == 'public' or not data.visibility %}selected="selected"{% endif %}>{{ _('Public') }}</option> <option value="private" {% if data.visibility == 'private' %}selected="selected"{% endif %}>{{ _('Private') }}</option> <option value="sub_project" {% if data.visibility == 'sub_project' %}selected="selected"{% endif %}>{{ _('Sub Project') }}</option> <option value="project" {% if data.visibility == 'project' %}selected="selected"{% endif %}>{{ _('Project') }}</option> <option value="organization" {% if data.visibility == 'organization' %}selected="selected"{% endif %}>{{ _('Organisation/Company/Institute') }}</option> </select>
- 将原有的
private布尔字段替换为自定义的visibility字符串字段,用于存储新的可见性状态值。
2. 扩展数据集元数据字段
如果使用ckanext-scheming,在你的数据集schema配置文件中添加以下字段定义:
- field_name: visibility label: Visibility preset: select choices: - value: public label: Public - value: private label: Private - value: sub_project label: Sub Project - value: project label: Project - value: organization label: Organisation/Company/Institute required: true
如果不使用scheming,通过自定义扩展的IPackageController钩子添加字段:
from ckan.plugins import SingletonPlugin, IPackageController from ckan.logic.schema import default_package_schema class VisibilityPlugin(SingletonPlugin): implements(IPackageController) def package_schema(self): schema = default_package_schema() # 添加visibility字段的验证规则与默认值 schema['visibility'] = [ unicode, lambda key, data, errors: data.setdefault(key, 'public') ] return schema def before_view(self, pkg_dict): # 兼容旧数据集,补充默认可见性值 if 'visibility' not in pkg_dict: pkg_dict['visibility'] = 'public' return pkg_dict
3. 权限控制逻辑实现
通过扩展的before_show钩子,根据不同可见性选项控制数据集访问权限:
from ckan.common import c def before_show(self, pkg_dict): user = c.userobj visibility = pkg_dict.get('visibility', 'public') # 公开数据集:所有人可见 if visibility == 'public': return pkg_dict # 私有数据集:仅所有者或系统管理员可见 if visibility == 'private': if user and (user.id == pkg_dict['creator_user_id'] or user.sysadmin): return pkg_dict raise Exception("无权限访问该数据集") # 子项目可见:仅子项目组成员可见(需根据实际子项目实现调整) if visibility == 'sub_project': sub_project_id = pkg_dict.get('sub_project_id') if user and sub_project_id and sub_project_id in [g.id for g in user.get_groups()]: return pkg_dict raise Exception("无权限访问该数据集") # 项目可见:仅项目组成员可见(需根据实际项目实现调整) if visibility == 'project': project_id = pkg_dict.get('project_id') if user and project_id and project_id in [g.id for g in user.get_groups()]: return pkg_dict raise Exception("无权限访问该数据集") # 组织可见:仅所属组织成员可见 if visibility == 'organization': org_id = pkg_dict.get('owner_org') if user and org_id and org_id in [o.id for o in user.get_groups('organization')]: return pkg_dict raise Exception("无权限访问该数据集") return pkg_dict
- 子项目/项目的权限逻辑需结合你系统中分组/项目的实际实现方式调整。
4. 兼容原有private字段
为保证旧功能正常运行,在数据创建/更新时同步private字段值:
def before_create(self, context, pkg_dict): pkg_dict['private'] = pkg_dict.get('visibility') != 'public' return pkg_dict def before_update(self, context, pkg_dict): pkg_dict['private'] = pkg_dict.get('visibility') != 'public' return pkg_dict
5. 前端展示优化
在数据集详情页(如package/read.html)添加可见性状态展示:
<div class="dataset-metadata-item"> <span class="label">{{ _('Visibility') }}:</span> <span class="value">{{ _(pkg.visibility.replace('_', ' ').title()) }}</span> </div>
内容的提问来源于stack exchange,提问作者Namwanza Ronald
相关产品推荐
相关产品推荐

