KeystoneJS 实战教程第二课:建立数据关联关系
前言
在上一课中,我们使用 KeystoneJS 搭建了一个简单的博客系统基础框架,包含了用户(User)列表和基本字段。本课将深入探讨如何在 KeystoneJS 中建立数据模型之间的关联关系,这是构建复杂应用的关键一步。
回顾上节课内容
我们目前有一个基本的用户模型配置:
// keystone.ts
import { config, list } from '@keystone-6/core';
import { allowAll } from '@keystone-6/core/access';
import { text } from '@keystone-6/core/fields';
export default config({
db: {
provider: 'sqlite',
url: 'file:./keystone.db',
},
lists: {
User: list({
access: allowAll,
fields: {
name: text({ validation: { isRequired: true } }),
email: text({ validation: { isRequired: true }, isIndexed: 'unique' }),
},
}),
},
});
重构代码结构
在添加新功能前,我们先优化代码结构,将列表定义提取到单独的对象中:
const lists = {
User: list({
access: allowAll,
fields: {
name: text({ validation: { isRequired: true } }),
email: text({ validation: { isRequired: true }, isIndexed: 'unique' }),
},
}),
};
这种结构更清晰,也便于后续维护和扩展。在实际项目中,你还可以考虑将不同列表拆分到单独的文件中。
创建文章(Post)模型
现在我们来添加文章模型,这是博客系统的核心内容:
const lists = {
// ...User配置
Post: list({
access: allowAll,
fields: {
title: text(),
},
}),
};
这里我们暂时只添加了标题字段,内容字段将在后续课程中添加。
建立用户与文章的关联
在关系型数据库中,表与表之间的关系非常重要。KeystoneJS 提供了强大的关系字段(relationship)来处理这种关联。
考虑我们的业务需求:
- 一个用户可以创建多篇文章
- 一篇文章只能由一个用户创建
这种一对多关系在 KeystoneJS 中可以通过双向关系字段实现:
import { relationship } from '@keystone-6/core/fields';
const lists = {
User: list({
// ...其他配置
fields: {
// ...其他字段
posts: relationship({ ref: 'Post.author', many: true }),
},
}),
Post: list({
// ...其他配置
fields: {
// ...其他字段
author: relationship({ ref: 'User.posts' }),
},
}),
};
关键点说明:
ref
属性指定了关联的另一方many: true
表示这是一个一对多关系- 关系是双向的,需要在两个模型中分别定义
优化管理界面体验
KeystoneJS 的管理界面提供了丰富的自定义选项。我们可以优化关系字段的显示方式,提升用户体验:
author: relationship({
ref: 'User.posts',
ui: {
displayMode: 'cards',
cardFields: ['name', 'email'],
inlineEdit: { fields: ['name', 'email'] },
linkToItem: true,
inlineCreate: { fields: ['name', 'email'] },
},
}),
这些配置实现了:
- 卡片式展示关联用户
- 显示用户姓名和邮箱
- 支持内联编辑用户信息
- 可以直接创建新用户
完整代码示例
// keystone.ts
import { config, list } from '@keystone-6/core';
import { allowAll } from '@keystone-6/core/access';
import { text, relationship } from '@keystone-6/core/fields';
const lists = {
User: list({
access: allowAll,
fields: {
name: text({ validation: { isRequired: true } }),
email: text({ validation: { isRequired: true }, isIndexed: 'unique' }),
posts: relationship({ ref: 'Post.author', many: true }),
},
}),
Post: list({
access: allowAll,
fields: {
title: text(),
author: relationship({
ref: 'User.posts',
ui: {
displayMode: 'cards',
cardFields: ['name', 'email'],
inlineEdit: { fields: ['name', 'email'] },
linkToItem: true,
inlineCreate: { fields: ['name', 'email'] },
},
}),
},
}),
};
export default config({
db: {
provider: 'sqlite',
url: 'file:./keystone.db',
},
lists,
});
总结
本课我们学习了:
- 如何优化 KeystoneJS 项目结构
- 创建新的内容模型(Post)
- 建立模型间的关联关系
- 自定义管理界面关系字段的显示方式
这些知识是构建复杂内容管理系统的基础。在下一课中,我们将学习如何实现文章的发布工作流,包括状态管理和发布时间设置等功能。
最佳实践建议
- 命名规范:关系字段的命名要清晰表达其业务含义
- 性能考虑:大量数据时,
many: true
的关系可能需要分页处理 - UI优化:根据实际业务需求选择最适合的关系展示方式
- 代码组织:随着模型增多,考虑将不同模型拆分到单独文件中
通过本课的学习,你应该已经掌握了 KeystoneJS 中关系处理的核心概念,能够为你的应用建立复杂的数据关联了。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考