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

Python/Django新手求助:如何用Django ORM实现多表数据查询

Django ORM 关联表查询指南(针对你的三张表)

嘿,作为Python和Django的新手,刚接触ORM时面对关联表确实容易犯难——别担心,我结合你的三张表结构,一步步给你讲清楚怎么用ORM获取数据!

第一步:先确认你的Django模型定义

首先得确保你的模型(models.py)正确映射了数据库表,外键关联要对应好,这是ORM查询的基础:

from django.db import models

class User(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=100)

    class Meta:
        db_table = 'USER'  # 匹配你数据库的大写表名

class InvestmentName(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=100)

    class Meta:
        db_table = 'INVESTMENT_NAME'

class Wallet(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, db_column='user_id')
    investment = models.ForeignKey(InvestmentName, on_delete=models.CASCADE, db_column='inv_id')
    date = models.DateField()
    quantity = models.DecimalField(max_digits=10, decimal_places=2)
    amount = models.DecimalField(max_digits=12, decimal_places=2)
    # 注意:数据库里的"current price"有空格,这里用db_column指定对应字段
    current_price = models.DecimalField(max_digits=10, decimal_places=2, db_column='current price')

    class Meta:
        db_table = 'WALLET'

小提醒:数据库字段带空格其实不太规范,后续如果有机会,建议改成current_price这类下划线命名,能减少很多不必要的麻烦。

第二步:常见查询场景示例

下面是你可能用到的几种查询需求,直接拿代码用就行:

1. 获取某个用户的所有钱包记录,同时显示对应的投资名称

比如要找id为1的用户的所有投资记录:

# 先获取目标用户
user = User.objects.get(id=1)
# 用select_related预加载关联的投资名称,避免多次查询数据库
wallet_records = Wallet.objects.filter(user=user).select_related('investment')

# 遍历输出详情
for record in wallet_records:
    print(f"用户名: {user.name}")
    print(f"投资产品: {record.investment.name}")
    print(f"日期: {record.date}, 数量: {record.quantity}, 投入金额: {record.amount}\n")

2. 获取所有投资产品的名称,以及对应的所有用户投资记录

# 用prefetch_related预加载关联的钱包记录,适合反向多关联查询
investments = InvestmentName.objects.prefetch_related('wallet_set').all()

for inv in investments:
    print(f"投资产品: {inv.name}")
    print("相关投资记录:")
    for wallet in inv.wallet_set.all():
        print(f"- 投资者: {wallet.user.name}, 日期: {wallet.date}, 当前单价: {wallet.current_price}")
    print("---")

3. 统计某个用户的总投资金额

from django.db.models import Sum

user = User.objects.get(id=1)
total_investment = Wallet.objects.filter(user=user).aggregate(total=Sum('amount'))['total']
print(f"用户{user.name}的累计投资金额: {total_investment}")

4. 查询某一天的所有钱包记录

from datetime import date

target_date = date(2024, 5, 20)
# 同时预加载用户和投资名称,一次性获取所有关联数据
daily_records = Wallet.objects.filter(date=target_date).select_related('user', 'investment')

for record in daily_records:
    print(f"用户: {record.user.name}, 投资产品: {record.investment.name}, 金额: {record.amount}")

实用小技巧

  • 用select_related处理正向外键/一对一关联,prefetch_related处理反向关联/多对多,能大幅提升查询效率,避免N+1查询问题。
  • 如果不确定查询对应的SQL语句,可以在查询后加.query查看,比如print(Wallet.objects.filter(user=user).select_related('investment').query),方便排查问题。

内容的提问来源于stack exchange,提问作者Maruti Nerli

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 04:04:46