REST 接口架构(中文译文)
原始 DeepWiki 页面:https://deepwiki.com/mayan-edms/Mayan-EDMS/3.4-rest-api-architecture
翻译时间:2026-05-27T08:44:32.143Z
翻译模型:deepseek-chat
原文字符数:15024
项目:Mayan EDMS (mayan-edms)
--- 好的,作为一名资深技术文档翻译专家,我将严格遵循您的要求,对这份 DeepWiki 技术文档进行完整、准确、符合中文技术写作习惯的翻译。
---
REST 接口架构
相关源文件
以下文件被用作生成此 Wiki 页面的上下文:
mayan/apps/cabinets/tests/test_wizard_steps.pymayan/apps/cabinets/wizard_steps.pymayan/apps/documents/apps.pymayan/apps/documents/icons.pymayan/apps/documents/links/document_version_links.pymayan/apps/documents/managers.pymayan/apps/documents/permissions.pymayan/apps/documents/tasks.pymayan/apps/documents/urls.pymayan/apps/documents/views/document_type_views.pymayan/apps/documents/views/document_version_views.pymayan/apps/documents/views/document_views.pymayan/apps/metadata/api.pymayan/apps/metadata/api_views.pymayan/apps/metadata/forms.pymayan/apps/metadata/models.pymayan/apps/metadata/serializers.pymayan/apps/metadata/tests/literals.pymayan/apps/metadata/tests/mixins.pymayan/apps/metadata/tests/test_forms.pymayan/apps/metadata/tests/test_models.pymayan/apps/metadata/tests/test_wizard_steps.pymayan/apps/metadata/urls.pymayan/apps/metadata/wizard_steps.pymayan/apps/quotas/tests/test_hooks.pymayan/apps/sources/wizards.pymayan/apps/tags/tests/literals.pymayan/apps/tags/tests/test_document_tag_api.pymayan/apps/tags/tests/test_indexing.pymayan/apps/tags/tests/test_tag_api.pymayan/apps/tags/tests/test_tag_document_api.pymayan/apps/tags/tests/test_wizard_steps.pymayan/apps/tags/wizard_steps.py
本文档描述了 Mayan EDMS 的 REST API 架构,涵盖了系统如何通过一个基于 Django REST Framework 的综合性 API 来暴露对其核心功能的程序化访问。该 API 为文档、元数据、文档类型及其他系统实体提供了完整的增删改查(CRUD)操作。
关于 Web 界面系统的信息,请参见用户界面系统。关于核心文档模型的详细信息,请参见文档管理核心。
API 框架与组件
Mayan EDMS 使用 Django REST Framework(DRF)实现了一个 REST API,该 API 为所有主要系统功能提供了程序化访问。API 架构由几个关键组件协同工作,以处理认证、权限、序列化和数据访问。
API 组件架构
graph TB
subgraph "API 层"
VIEWS["API 视图<br/>ListCreateAPIView<br/>RetrieveUpdateDestroyAPIView"]
SERIALIZERS["序列化器<br/>HyperlinkedModelSerializer<br/>DynamicSerializerField"]
PERMISSIONS["权限系统<br/>mayan_object_permissions<br/>mayan_external_object_permissions"]
end
subgraph "URL 路由"
API_URLS["api_urls 列表<br/>文档 API URLs<br/>元数据 API URLs"]
URL_PATTERNS["URL 模式<br/>REST API 命名空间"]
end
subgraph "数据访问"
MIXINS["API 视图混入<br/>ExternalObjectAPIViewMixin<br/>MetadataTypeFilterAPIMixin"]
ACL["访问控制列表<br/>查询集过滤"]
MODELS["Django 模型<br/>Document, DocumentType<br/>MetadataType"]
end
subgraph "动态特性"
DYNAMIC_FIELDS["DynamicSerializerField<br/>字段选择"]
FILTERED_FIELDS["FilteredPrimaryKeyRelatedField<br/>基于权限的过滤"]
end
VIEWS --> SERIALIZERS
VIEWS --> PERMISSIONS
VIEWS --> MIXINS
SERIALIZERS --> DYNAMIC_FIELDS
SERIALIZERS --> FILTERED_FIELDS
API_URLS --> VIEWS
MIXINS --> ACL
ACL --> MODELS
PERMISSIONS --> ACL
来源:mayan/apps/metadata/api_views.py:22-90, mayan/apps/metadata/serializers.py:24-144, mayan/apps/documents/urls.py:522-688
应用级 API 注册
Mayan EDMS 中的每个 Django 应用都通过 MayanAppConfig 系统声明其 REST API 能力。应用通过设置 has_rest_api = True 来表明其提供了 API 端点,并注册动态序列化器以实现跨应用的字段选择。
graph LR
subgraph "应用配置"
APP_CONFIG["MayanAppConfig<br/>has_rest_api = True"]
READY_METHOD["ready() 方法<br/>API 注册"]
end
subgraph "动态注册"
DYNAMIC_REG["DynamicSerializerField.add_serializer()<br/>跨应用序列化"]
SERIALIZER_CLASS["序列化器类<br/>DocumentSerializer<br/>MetadataTypeSerializer"]
end
APP_CONFIG --> READY_METHOD
READY_METHOD --> DYNAMIC_REG
DYNAMIC_REG --> SERIALIZER_CLASS
来源:mayan/apps/documents/apps.py:212, mayan/apps/documents/apps.py:285-288
URL 结构与路由
该 API 使用结构化的 URL 模式,将常规 Web 视图与 API 端点区分开来。每个应用都使用一致的命名约定,将其 API URL 贡献给一个集中式的路由系统。
API URL 组织
graph TB
subgraph "URL 结构"
ROOT_API["/api/"]
DOC_URLS["文档 API<br/>/api/documents/"]
META_URLS["元数据 API<br/>/api/metadata_types/"]
DOC_TYPE_URLS["文档类型 API<br/>/api/document_types/"]
end
subgraph "文档端点"
DOC_LIST["/api/documents/<br/>GET, POST"]
DOC_DETAIL["/api/documents/{id}/<br/>GET, PUT, PATCH, DELETE"]
DOC_UPLOAD["/api/documents/upload/<br/>POST"]
end
subgraph "元数据端点"
META_LIST["/api/metadata_types/<br/>GET, POST"]
META_DETAIL["/api/metadata_types/{id}/<br/>GET, PUT, PATCH, DELETE"]
DOC_META["/api/documents/{id}/metadata/<br/>GET, POST"]
end
ROOT_API --> DOC_URLS
ROOT_API --> META_URLS
ROOT_API --> DOC_TYPE_URLS
DOC_URLS --> DOC_LIST
DOC_URLS --> DOC_DETAIL
DOC_URLS --> DOC_UPLOAD
META_URLS --> META_LIST
META_URLS --> META_DETAIL
META_URLS --> DOC_META
来源:mayan/apps/documents/urls.py:522-688, mayan/apps/metadata/urls.py:100-129
URL 模式实现
API URL 被组织成针对不同实体类型的独立列表,然后合并成一个主 api_urls 列表。这种模块化方法允许每个功能区域维护自己的 URL 模式,同时为整个 API 结构做出贡献。
| URL 模式 | 视图类 | 用途 |
|---|---|---|
^documents/$ | APIDocumentListView | 列出和创建文档 |
^documents/(?P<document_id>[0-9]+)/$ | APIDocumentDetailView | 文档详情操作 |
^metadata_types/$ | APIMetadataTypeListView | 元数据类型管理 |
^documents/(?P<document_id>[0-9]+)/metadata/$ | APIDocumentMetadataListView | 文档元数据操作 |
来源:mayan/apps/documents/urls.py:528-563, mayan/apps/metadata/urls.py:102-128
序列化器与数据表示
该 API 使用 Django REST Framework 序列化器来处理 JSON 和 Django 模型实例之间的数据转换。Mayan EDMS 通过支持权限感知的字段过滤和动态字段选择功能,扩展了标准的 DRF 序列化器。
序列化器架构
graph TB
subgraph "基础序列化器"
HYPER_SERIALIZER["HyperlinkedModelSerializer<br/>基于 URL 的引用"]
MODEL_SERIALIZER["ModelSerializer<br/>标准字段"]
end
subgraph "自定义字段"
FILTERED_PK["FilteredPrimaryKeyRelatedField<br/>基于权限的过滤"]
DYNAMIC_FIELD["DynamicSerializerField<br/>跨应用字段选择"]
SERIALIZER_METHOD["SerializerMethodField<br/>自定义 URL 生成"]
end
subgraph "校验"
DJANGO_VALIDATION["Django 模型校验<br/>full_clean()"]
CUSTOM_VALIDATION["自定义校验<br/>validate() 方法"]
end
HYPER_SERIALIZER --> FILTERED_PK
MODEL_SERIALIZER --> DYNAMIC_FIELD
FILTERED_PK --> DJANGO_VALIDATION
DYNAMIC_FIELD --> CUSTOM_VALIDATION
SERIALIZER_METHOD --> HYPER_SERIALIZER
来源:mayan/apps/metadata/serializers.py:40-86, mayan/apps/rest_api/fields.py:30
权限感知的字段过滤
FilteredPrimaryKeyRelatedField 和 FilteredSimplePrimaryKeyRelatedField 类提供了对相关对象的基于权限的过滤。这些字段会根据请求用户的权限自动限制可用的选项。
graph LR
subgraph "字段类型"
FILTERED_PK["FilteredPrimaryKeyRelatedField<br/>source_model<br/>source_permission"]
SIMPLE_PK["FilteredSimplePrimaryKeyRelatedField<br/>write_only=True"]
end
subgraph "权限检查"
ACL_FILTER["AccessControlList.restrict_queryset()<br/>用户权限过滤"]
QUERYSET["过滤后的查询集<br/>仅可访问的对象"]
end
FILTERED_PK --> ACL_FILTER
SIMPLE_PK --> ACL_FILTER
ACL_FILTER --> QUERYSET
来源:mayan/apps/metadata/serializers.py:45-49, mayan/apps/rest_api/relations.py:14-16
API 视图与权限系统
Mayan EDMS 中的 API 视图扩展了 Django REST Framework 的通用视图,集成了一个与访问控制列表(ACL)框架相结合的综合性权限系统。视图同时处理对象级和视图级的权限。
视图类层次结构
graph TB
subgraph "DRF 基础视图"
LIST_CREATE["ListCreateAPIView<br/>GET, POST 操作"]
RETRIEVE_UPDATE["RetrieveUpdateDestroyAPIView<br/>GET, PUT, PATCH, DELETE"]
end
subgraph "Mayan 混入"
EXT_OBJ_MIXIN["ExternalObjectAPIViewMixin<br/>相关对象处理"]
FILTER_MIXIN["MetadataTypeFilterAPIMixin<br/>基于权限的过滤"]
end
subgraph "具体视图"
DOC_META_LIST["APIDocumentMetadataListView<br/>文档元数据操作"]
META_TYPE_VIEW["APIMetadataTypeView<br/>元数据类型管理"]
end
LIST_CREATE --> DOC_META_LIST
RETRIEVE_UPDATE --> META_TYPE_VIEW
EXT_OBJ_MIXIN --> DOC_META_LIST
FILTER_MIXIN --> DOC_META_LIST
来源:mayan/apps/metadata/api_views.py:22-56, mayan/apps/metadata/api_views.py:109-129
权限配置
API 视图通过两个主要属性来定义权限:mayan_object_permissions 用于单个对象访问,mayan_view_permissions 用于视图级操作。
| 权限类型 | 用途 | 示例 |
|---|---|---|
mayan_object_permissions | 每个对象的访问控制 | {'GET': (permission_document_view,)} |
mayan_view_permissions | 视图级操作 | {'POST': (permission_metadata_type_create,)} |
mayan_external_object_permissions | 相关对象权限 | 用于元数据的外部文档访问 |
来源:mayan/apps/metadata/api_views.py:31-37, mayan/apps/metadata/api_views.py:97-98
外部对象处理
ExternalObjectAPIViewMixin 提供了一种处理相关对象操作的模式,例如管理文档元数据,其中文档是外部对象,而元数据条目是被操作的主要对象。
外部对象模式
graph LR
subgraph "请求处理"
URL_PARAMS["URL 参数<br/>document_id, metadata_id"]
EXT_OBJ_LOOKUP["外部对象查找<br/>get_external_object()"]
end
subgraph "对象解析"
EXT_QUERYSET["external_object_queryset<br/>Document.valid.all()"]
EXT_PERMS["external_object_permissions<br/>权限检查"]
RESOLVED_OBJ["已解析的外部对象<br/>self.external_object"]
end
subgraph "查询集过滤"
GET_QUERYSET["get_queryset()<br/>按外部对象过滤"]
FINAL_QUERYSET["最终查询集<br/>仅相关对象"]
end
URL_PARAMS --> EXT_OBJ_LOOKUP
EXT_OBJ_LOOKUP --> EXT_QUERYSET
EXT_QUERYSET --> EXT_PERMS
EXT_PERMS --> RESOLVED_OBJ
RESOLVED_OBJ --> GET_QUERYSET
GET_QUERYSET --> FINAL_QUERYSET
来源:mayan/apps/metadata/api_views.py:22-55, mayan/apps/rest_api/api_view_mixins.py:7
动态字段选择与序列化
Mayan EDMS 实现了一个动态序列化系统,允许应用注册序列化器以实现跨应用的字段包含。这使得 API 响应可以灵活地包含来自不同应用的相关数据。
动态序列化器注册
DynamicSerializerField 系统允许应用为其模型注册序列化器,从而使其他应用能够在其 API 响应中包含这些模型的序列化数据。
graph TB
subgraph "注册过程"
APP_READY["App ready() 方法<br/>序列化器注册"]
ADD_SERIALIZER["DynamicSerializerField.add_serializer()<br/>类 -> 序列化器映射"]
end
subgraph "运行时使用"
FIELD_REQUEST["API 字段请求<br/>动态字段选择"]
SERIALIZER_LOOKUP["序列化器类查找<br/>已注册的映射"]
SERIALIZED_DATA["序列化的相关数据<br/>跨应用集成"]
end
APP_READY --> ADD_SERIALIZER
ADD_SERIALIZER --> SERIALIZER_LOOKUP
FIELD_REQUEST --> SERIALIZER_LOOKUP
SERIALIZER_LOOKUP --> SERIALIZED_DATA
来源:mayan/apps/documents/apps.py:285-288, mayan/apps/rest_api/fields.py:30
序列化器字段类型
| 字段类型 | 用途 | 使用场景 |
|---|---|---|
DynamicSerializerField | 跨应用序列化 | 包含相关模型数据 |
FilteredPrimaryKeyRelatedField | 权限过滤的关系 | 安全对象引用 |
SerializerMethodField | 自定义 URL 生成 | 创建 HATEOAS 链接 |
来源:mayan/apps/metadata/serializers.py:91-99, mayan/apps/metadata/serializers.py:51