Django原生SQL求和查询vs循环求和:已获记录的特殊场景处理
解决Django中已获取记录后的总价与总折扣额计算
哈哈,这种“已经把数据捞出来才想起要统计汇总”的场景我太熟悉了!既然你已经通过原生SQL拿到了包含书籍信息的记录列表,完全不用再回头去数据库里跑SUM()了,直接用Python处理这些内存里的数据就好,简单又高效。
分两种情况处理:
情况1:拿到的是Django Model实例列表(比如用raw()查询返回的结果)
假设你的书籍模型是这样定义的:
from django.db import models class Book(models.Model): name = models.CharField(max_length=100) price = models.DecimalField(max_digits=10, decimal_places=2) discount_rate = models.FloatField() # 比如0.15代表15%的折扣
你已经通过原生SQL获取了实例列表:
books = Book.objects.raw("SELECT id, name, price, discount_rate FROM myapp__book WHERE ...")
那计算总价和总折扣额就直接用生成器表达式求和:
# 计算所有书籍的总价 total_price = sum(book.price for book in books) # 计算总折扣额(单本价格×折扣率的总和) total_discount = sum(book.price * book.discount_rate for book in books)
情况2:拿到的是原生SQL返回的字典/元组列表(比如用connection.cursor()执行的查询)
如果是直接用数据库游标执行原生SQL,返回的是元组或字典:
from django.db import connection with connection.cursor() as cursor: cursor.execute("SELECT name, price, discount_rate FROM myapp_book WHERE ...") # 如果是元组列表 records = cursor.fetchall() # 或者如果是字典列表(需要额外配置游标) # records = cursor.fetchdict()
针对元组列表的计算:
total_price = sum(record[1] for record in records) total_discount = sum(record[1] * record[2] for record in records)
针对字典列表的计算:
total_price = sum(r['price'] for r in records) total_discount = sum(r['price'] * r['discount_rate'] for r in records)
小提示
如果你的数据量特别大(比如上万条以上),其实还是推荐直接在SQL里用SUM()来计算,毕竟数据库做聚合运算的效率更高。但如果数据量不大,或者已经有其他逻辑需要先拿到完整记录,那用Python在内存里计算完全没问题~
内容的提问来源于stack exchange,提问作者Bahman Rouhani
相关产品推荐
相关产品推荐

