在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注入风险 - 把原生查询的结果手动转换成你需要的字典结构
注意事项
- 数据唯一性:确保每个
(ticker, date)组合在两张表中都是唯一的,否则关联后会出现重复数据 - 左连接需求:如果需要保留其中一张表中存在但另一张表不存在的记录,可以把
JOIN改成LEFT JOIN - 日期格式:请求中的日期参数要符合
YYYY-MM-DD格式,和模型中DateField的存储格式一致
内容的提问来源于stack exchange,提问作者Chris Evans
相关产品推荐
相关产品推荐

