Files
upstream-twenty/packages/twenty-docs/l/zh/user-guide/data-model/how-tos/create-many-to-many-relations.mdx
upstream-mirror e7da97194a
Some checks failed
App Prod-Parity E2E Dispatch / dispatch (push) Failing after 10s
CD Storybook UI / build (push) Failing after 3m25s
CD Storybook UI / dispatch (push) Has been skipped
CD deploy main / website-changed-files (push) Successful in 18m8s
CI Agent Skills / changed-files-check (push) Successful in 18m9s
CI Create App E2E minimal / changed-files-check (push) Successful in 24s
CI Create App / changed-files-check (push) Successful in 26s
CI Docs / changed-files-check (push) Successful in 26s
CI Emails / changed-files-check (push) Successful in 28s
CI Example App Hello World / changed-files-check (push) Successful in 23s
CI Front / changed-files-check (push) Has been skipped
CI Example App Postcard / changed-files-check (push) Successful in 27s
CI UI / changed-files-check (push) Has been skipped
CI Utils Test / changed-files-check (push) Successful in 45s
CI Twenty Apps / discover (push) Successful in 1m3s
CD deploy main / deploy-main (push) Failing after 3s
CI Agent Skills / agent-skills-validate (push) Has been skipped
CI Create App / create-app-test (lint) (push) Has been skipped
CI Emails / emails-test (push) Has been skipped
CI Front / front-task (lingui:compile) (push) Has been skipped
CI Front / front-task (lint) (push) Has been skipped
CI Example App Postcard / example-app-postcard (push) Has been skipped
CI UI / ui-task (lint) (push) Has been skipped
CI UI / ui-task (pack-size) (push) Has been skipped
CI UI / ui-task (size) (push) Has been skipped
CI UI / ui-task (test) (push) Has been skipped
CI UI / ui-task (typecheck) (push) Has been skipped
CI Utils Test / utils-test (push) Has been skipped
CI Twenty Apps / ${{ matrix.app.name }} (push) Has been skipped
CI Emails / ci-emails-status-check (push) Successful in 2s
CI Example App Hello World / ci-example-app-hello-world-status-check (push) Successful in 2s
CI Example App Postcard / ci-example-app-postcard-status-check (push) Successful in 3s
CI UI / ui-sb-test (push) Has been skipped
CI Utils Test / ci-utils-test-status-check (push) Successful in 2s
CI Twenty Apps / ci-twenty-apps-status-check (push) Successful in 2s
CI UI / ci-ui-status-check (push) Successful in 2s
CI Desktop / desktop (push) Failing after 1m8s
Push docs to Crowdin / Push documentation to Crowdin (push) Failing after 55s
Push translations to Crowdin / Extract and upload translations (push) Failing after 5s
Push website translations to Crowdin / Extract and upload website translations (push) Failing after 5s
CI Create App / create-app-test (test) (push) Has been skipped
CI Create App / create-app-test (typecheck) (push) Has been skipped
CI Docs / docs-lint (push) Has been skipped
CI Example App Hello World / example-app-hello-world (push) Has been skipped
CI Front / front-task (lingui:extract) (push) Has been skipped
CI Front / front-task (test) (push) Has been skipped
CI Front / front-task (typecheck) (push) Has been skipped
CI UI / ui-sb-build (push) Failing after 1m32s
CI Twenty Apps / ${{ matrix.app.name }} (${{ matrix.server-source }}) (push) Has been skipped
CI Agent Skills / agent-skills-publish (push) Has been skipped
CI Create App / ci-create-app-status-check (push) Successful in 2s
CI Agent Skills / agent-skills-remote-source (push) Has been skipped
CI Create App E2E minimal / create-app-e2e-minimal (push) Has been cancelled
CI E2E Main / e2e-test (push) Has been cancelled
CI Front / front-sb-build (push) Has been cancelled
CI Front / front-build (push) Has been cancelled
CI Create App E2E minimal / ci-create-app-e2e-minimal-status-check (push) Has been cancelled
CI E2E Main / ci-e2e-main-status-check (push) Has been cancelled
CI E2E Main / notify-main-ci-failure (push) Has been cancelled
CI E2E Main / qa-scout-comment (push) Has been cancelled
CI Front / front-sb-test (push) Has been cancelled
CI Front / front-sb-screenshots (push) Has been cancelled
CI Front / ci-front-status-check (push) Has been cancelled
DPA Sub-Processor Sync / sync-subprocessors (push) Failing after 3s
AI Catalog Sync / sync-catalog (push) Failing after 3s
snapshot of https://github.com/twentyhq/twenty.git (main, 2026-09-17; blobs > 131072B omitted)
2026-09-17 23:28:13 +05:00

176 lines
6.2 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: 创建多对多关系
description: 当双方都有多个条目时,使用连接对象将记录相互关联。
---
多对多关系使您能够在关系双方连接多个记录。 例如:许多 People 可以参与许多 Projects,并且每个 Project 可以包含许多 People。
<Warning>
**Beta 功能**:连接关系目前处于 Beta 阶段。 在按照本指南操作之前,请先在 **Settings → Community → Features** 中启用它们。
</Warning>
<Note>
此功能还需要启用 **Advanced mode**(在 Settings 左下角切换)。
</Note>
## 何时使用多对多
当关系双方都可能存在多个关联时,请使用多对多:
| 关系 | 示例 |
| ----------------- | -------------------------- |
| People ↔ Projects | 一个人参与多个项目;一个项目包含多名团队成员 |
| Companies ↔ Tags | 一个公司可以拥有多个标签;一个标签可以应用于多家公司 |
| Products ↔ Orders | 一个产品可以出现在多个订单中;一个订单包含多个产品 |
## 工作原理
Twenty 在多对多关系中使用 **连接对象** 模式。 连接对象位于两个对象之间,并存储它们之间的关联:
```
People ←→ Project Assignments ←→ Projects
```
该 **Project Assignments** 对象(连接对象)具有:
* 到 People 的关系(多对一)
* 到 Projects 的关系(多对一)
启用连接关系开关后,Twenty 将直接显示已关联的记录,而不再展示中间的连接对象记录。
## 先决条件
1. **在 Beta 功能中启用连接关系**:前往 **Settings → Community → Features** 并启用 **Junction Relations**
2. **启用 Advanced mode**:在 Settings 侧边栏左下角开启 **Advanced mode**
3. 规划您的数据模型:
* 您要连接哪两个对象?
* 连接对象应如何命名?
## 步骤 1:创建连接对象
首先,创建用于保存关联的中间对象。
1. 进入 **设置 → 数据模型**
2. 点击 **+ 添加对象**
3. 使用描述性名称(例如,"Project Assignment"、"Team Member"、"Product Order")
4. 将“跳过创建名称字段”切换为开启
<img src="/images/user-guide/fields/new-pivot-object.png" alt="新建连接对象" />
5. 单击 **保存**
<Tip>
**命名约定**:使用能描述关系的名称,例如 "Project Assignment" 或 "Team Membership"。 这会让数据模型更易理解。
</Tip>
## 第 2 步:在对象与连接对象之间创建关系
从您的两个对象分别向连接对象添加关系字段。
### 第一条关系(对象 A → 连接对象)
1. 在 **Settings → Data Model** 中选择您的第一个对象
2. 单击 **+ 添加关系**
3. 选择连接对象(例如,"Project Assignments")
4. 将关系类型设置为 **One-To-Many**(一个人可以关联到多个分配)
5. 为这些字段命名:
* People 上的字段:例如,"Project Assignments"
* 连接对象上的字段:例如,"Person"
6. 单击 **保存**
### 第二条关系(对象 B → 连接对象)
1. 在 **Settings → Data Model** 中选择您的第二个对象
2. 单击 **+ 添加关系**
3. 选择连接对象(例如,"Project Assignments")
4. 将关系类型设置为 **One-To-Many**(一个项目可以关联到多个分配)
5. 启用 **"This is a relation to a Junction Object"**
<img src="/images/user-guide/fields/junction-relation-toggle.png" style={{width:'100%'}} />
6. 为这些字段命名:
* 连接对象上的字段:例如,"Project"
* Projects 上的字段:例如,"Team Members"
7. 单击 **保存**
## 步骤 3:配置连接关系的显示方式
现在配置源对象以直接显示已关联的记录,跳过中间的连接对象。
1. 进入 **设置 → 数据模型**
2. 选择第一个对象(例如,"People")
3. 找到指向连接对象的关系字段(例如,"Project Assignments")
4. 点击以编辑该字段
5. 启用 **"This is a relation to a Junction Object"**
6. 选择 **Target relation**(例如,"Project" —— 连接对象上指向另一侧的字段)
7. 单击 **保存**
## 结果
配置完成后:
* 在 **Person** 记录中,"Project Assignments" 字段将直接显示 **Projects**(而非分配记录)
* 在 **Project** 记录中,"Team Members" 字段将直接显示 **People**
连接对象仍然存在并存储关联,但 UI 呈现的是更简洁的多对多视图。
## 示例:People ↔ Projects
以下是完整的操作演示:
### 创建连接对象
* 名称:**Project Assignment**
* 描述:"将人员与其参与的项目关联起来"
### 添加关系
1. **People → Project Assignment**
* 类型:One-to-Many
* People 上的字段:"Project Assignments"
* Assignment 上的字段:"Person"
2. **Projects → Project Assignment**
* 类型:One-to-Many
* Projects 上的字段:"Team Members"
* Assignment 上的字段:"Project"
### 配置连接关系显示
1. 在 **People** 对象上:
* 编辑 "Project Assignments" 字段
* 启用连接关系开关
* 目标:"Project"
2. 在 **Projects** 对象上:
* 编辑 "Team Members" 字段
* 启用连接关系开关
* 目标:"Person"
### 开始使用
* 打开某个 Person 记录 → 直接查看其 Projects
* 打开某个 Project 记录 → 直接查看其团队成员
* 可从任一侧创建新的关联
## 为关联添加额外数据
由于连接对象是一个真实对象,您可以添加自定义字段来存储关系相关的信息:
* **角色**:"Developer"、"Designer"、"Manager"
* **开始日期**:当人加入项目时
* **分配时长**:每周在该项目上的工时
要访问这些数据,请直接导航到连接对象,或通过 API 查询。
## 限制
* **CSV 导入/导出**:不支持直接导入多对多关系。 请改为将记录导入连接对象。
* **筛选器**:按多对多关系进行筛选的选项可能有限。
## 相关内容
* [关系字段](/l/zh/user-guide/data-model/capabilities/relation-fields) — 关系类型说明
* [创建自定义对象](/l/zh/user-guide/data-model/how-tos/create-custom-objects) — 如何创建对象
* [创建关系字段](/l/zh/user-guide/data-model/how-tos/create-relation-fields) — 基本关系设置