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

在Django视图中关联SSALiReport与NELiReport模型实现联合查询

Django实现关联SSALiReport和NELiReport生成FullReport数据结构

嘿,我来帮你搞定这个在Django视图中合并两张报表数据的需求!根据你的模型定义和SQL语句,我给你两种可行的实现方式,你可以根据自己的偏好选择。

方法一:使用Django ORM(推荐)

这种方式符合Django的最佳实践,能自动处理SQL注入,而且代码更易维护。我们可以通过annotate和F()表达式来关联两张表的ticker和date字段,提取需要的字段:

from django.db.models import F
from django.http import JsonResponse

def full_report_view(request):
    # 获取请求中的日期参数(可选)
    target_date = request.GET.get('date')
    
    # 构建查询集:关联SSALiReport和NELiReport,匹配ticker和date
    queryset = SSALiReport.objects.filter(
        nelireport__ticker=F('ticker'),
        nelireport__date=F('date')
    )
    
    # 如果有日期参数,添加过滤条件
    if target_date:
        queryset = queryset.filter(date=target_date)
    
    # 提取需要的字段,合并成目标结构
    full_reports = queryset.annotate(
        sentiment=F('nelireport__sentiment'),
        clout=F('nelireport__clout')
    ).values(
        'date', 'market', 'prediction', 'price', 'ticker', 'sentiment', 'clout'
    )
    
    # 转换成列表并返回JSON
    return JsonResponse(list(full_reports), safe=False)

代码解释:

  • F('nelireport__sentiment'):通过Django自动生成的反向关联(小写模型名)获取NELiReport的字段
  • values():指定需要返回的字段,直接生成符合你需求的字典结构
  • 日期过滤通过request.GET.get('date')获取参数,比如请求/full-report/?date=2018-05-15就能得到指定日期的数据

方法二:执行原生SQL

如果你更习惯用原生SQL(就是你提供的那条语句),Django也支持直接执行原生查询,这种方式更灵活,适合复杂场景:

from django.http import JsonResponse

def full_report_view(request):
    target_date = request.GET.get('date')
    
    # 基础SQL语句,使用JOIN替代逗号分隔表(更规范)
    base_sql = """
        SELECT 
            s.date, s.market, s.prediction, s.price, s.ticker,
            n.sentiment, n.clout
        FROM api_ssali_report s
        JOIN api_neli_report n ON s.ticker = n.ticker AND s.date = n.date
    """
    
    # 如果有日期参数,添加WHERE条件
    params = []
    if target_date:
        base_sql += " WHERE s.date = %s"
        params.append(target_date)
    
    # 执行原生查询
    raw_reports = SSALiReport.objects.raw(base_sql, params)
    
    # 转换为目标字典格式
    full_reports = []
    for report in raw_reports:
        full_reports.append({
            'date': str(report.date),
            'market': report.market,
            'prediction': report.prediction,
            'price': report.price,
            'ticker': report.ticker,
            'sentiment': report.sentiment,
            'clout': report.clout
        })
    
    return JsonResponse(full_reports, safe=False)

代码解释:

  • 用JOIN替代了原始SQL中的逗号分隔表,这是更标准的关联写法
  • 使用%s作为参数占位符,避免SQL注入风险
  • 把原生查询的结果手动转换成你需要的字典结构

注意事项

  1. 数据唯一性:确保每个(ticker, date)组合在两张表中都是唯一的,否则关联后会出现重复数据
  2. 左连接需求:如果需要保留其中一张表中存在但另一张表不存在的记录,可以把JOIN改成LEFT JOIN
  3. 日期格式:请求中的日期参数要符合YYYY-MM-DD格式,和模型中DateField的存储格式一致

内容的提问来源于stack exchange,提问作者Chris Evans

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:59:45