如何在NestJS的Prisma中实现类似Django模型的自定义取值方法?
在NestJS + Prisma + TypeScript中实现自动转换字段值
针对你需要每次获取Mongo集合中amount字段时自动除以100的需求,有两种常用实现方式,以下是具体方案:
方法一:使用Prisma Client扩展(推荐)
Prisma Client扩展允许你在客户端层面扩展模型,添加自定义计算字段或方法,所有查询都会自动应用转换逻辑,无需手动处理。
1. 扩展Prisma服务
在你的PrismaService中添加扩展逻辑:
import { Injectable, OnModuleInit } from '@nestjs/common'; import { PrismaClient } from '@prisma/client'; @Injectable() export class PrismaService extends PrismaClient implements OnModuleInit { async onModuleInit() { await this.$connect(); } // 返回扩展后的Prisma客户端 getExtendedClient() { return this.$extends({ // 定义计算字段:自动将amount除以100后返回为formattedAmount result: { // 替换为你的集合名称(比如你的集合是`Book`就写book) book: { formattedAmount: { // 指定需要依赖的原始字段 needs: { amount: true }, // 计算逻辑 compute(book) { return book.amount / 100; }, }, }, }, // 也可以添加自定义方法(可选) model: { book: { getFormattedAmount: (book) => book.amount / 100, }, }, }); } }
2. 在业务服务中使用扩展客户端
import { Injectable } from '@nestjs/common'; import { PrismaService } from './prisma.service'; @Injectable() export class BookService { constructor(private prisma: PrismaService) {} async getBookById(id: string) { const extendedPrisma = this.prisma.getExtendedClient(); // 查询时无需额外处理,返回的book对象会自动包含formattedAmount字段 const book = await extendedPrisma.book.findUnique({ where: { id }, }); return book; } // 调用自定义方法的示例(可选) async getBookFormattedAmount(id: string) { const extendedPrisma = this.prisma.getExtendedClient(); const book = await extendedPrisma.book.findUnique({ where: { id }, }); return extendedPrisma.book.getFormattedAmount(book); } }
方法二:在NestJS服务层封装转换逻辑
如果不想使用Prisma扩展,可以在业务服务中手动封装转换方法,每次查询后处理字段值:
import { Injectable } from '@nestjs/common'; import { PrismaService } from './prisma.service'; @Injectable() export class BookService { constructor(private prisma: PrismaService) {} // 封装字段转换逻辑 private formatBookAmount(book: any) { return { ...book, formattedAmount: book.amount / 100, }; } async getBookById(id: string) { const book = await this.prisma.book.findUnique({ where: { id }, }); return this.formatBookAmount(book); } async getAllBooks() { const books = await this.prisma.book.findMany(); return books.map(this.formatBookAmount); } }
方案对比
- Prisma扩展:更符合Prisma最佳实践,自动处理所有查询的字段转换,TypeScript类型提示完整,无需重复编写转换逻辑。
- 服务层封装:实现简单,适合小型项目或临时需求,但需要手动在每个查询方法中调用转换函数,代码冗余度较高。
内容的提问来源于stack exchange,提问作者Harsh Gupta
相关产品推荐
相关产品推荐

