如何编写高级 Django ORM 查询
Posted
技术标签:
【中文标题】如何编写高级 Django ORM 查询【英文标题】:How write advance Django ORM query 【发布时间】:2017-12-22 01:13:39 【问题描述】:为了简化事情,假设我有一个模型 StockIOLog。
class StockIOLog(models.Model):
pid = models.IntegerField()
name= models.CharField(max_length=50)
type= models.IntegerField()
stock = models.IntegerField()
它包含以下数据:
pid | name | batch | type | quantity
------------------------------------------------
1 | Napa | AB | 0 | 100
------------------------------------------------
1 | Napa | AA | 0 | 100
------------------------------------------------
2 | Amod | AA | 0 | 100
------------------------------------------------
2 | Amod | CA | 0 | 100
------------------------------------------------
1 | Napa | AB | 1 | 10
------------------------------------------------
1 | Napa | AB | 1 | 5
------------------------------------------------
1 | Napa | AA | 1 | 20
------------------------------------------------
2 | Amod | AA | 1 | 10
------------------------------------------------
2 | Amod | AA | 1 | 50
------------------------------------------------
2 | Amod | CA | 1 | 5
------------------------------------------------
2 | Amod | CA | 1 | 15
type 0 表示产品已购买,type 1 表示产品已消耗,现在我想分批计算每个产品的总库存。
通过运行以下 SQL 查询
SELECT pid, name, batch, SUM(in) - SUM(out) as stock FROM (
SELECT pid, name, type SUM(quantity) as in, 0 as out from `qset` WHERE type=0 GROUP BY pid,type,batch as a
UNION
SELECT pid, name, type 0 as in, SUM(quantity) as out from `qset` WHERE type=1 GROUP BY pid,type,batch as b
) ac table_a
我得到以下查询集
pid | name | batch | stock
-----------------------------------
1 | Napa | AB | 85
-----------------------------------
1 | Napa | AA | 80
-----------------------------------
2 | Amod | AA | 40
-----------------------------------
2 | Amod | CA | 80
django ORM中如何做类似的事情?
【问题讨论】:
SQL查询的问题很难理解。你能解释一下这个场景吗? @Md.Al-Amin 更简要地更新了问题 【参考方案1】:也许不是最好的答案,但您可以通过以下查询在字典中获取 purchased
和 consumed
from django.db.models import When, F, IntegerField, Sum, Count
from .models import StockIOLog
values = (StockIOLog.objects.all().values("pid", "name", "batch").annotate(
purchased=Sum(Case(When(type=1, then=F("stock")),
output_filed=IntegerField())),
consumed=Sum(Case(When(type=0, then=F("stock")),
output_field=IntegerField())))
)
【讨论】:
以上是关于如何编写高级 Django ORM 查询的主要内容,如果未能解决你的问题,请参考以下文章
在使用 ORM 的 Django 中,如何对不同的值进行多个自连接
使用 Rest API 编写复杂查询的 Django ORM