You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 15:22:47