我有類別和項目。這些項目有一個結束字段(日期時間)。現在我需要列出所有類別,並在將來顯示相關項目數量和項目數量。舉例:如何註釋日期時間過濾的計數?
- Cat Foo,2件物品,未來1件。
- Cat n,n items n in the future。
該列表將很大。所以數據庫必須完成繁重的工作並註釋item_count
和future_item_count
。
型號:
from django.db import models
class Cat(models.Model):
title = models.CharField(max_length=200)
class Item(models.Model):
cat = models.ForeignKey(Cat)
title = models.CharField(max_length=200)
end = models.DateTimeField()
創建類別和兩個相關項目。一個在過去,一個在未來:
from datetime import timedelta
from django.utils import timezone
cat = Cat(title='Cat 1')
cat.save()
item_1 = Item(cat=cat, title="Item 1", end=timezone.now() - timedelta(days=1))
item_1.save()
item_2 = Item(cat=cat, title="Item 2", end=timezone.now() + timedelta(days=1))
item_2.save()
當我批註ITEM_COUNT它按預期工作:
from django.db.models import Count
Cat.objects.all().annotate(
item_count=Count('item')).values('title', 'item_count')
# [{'item_count': 2, 'title': u'Cat 1'}]
我不能做批註通過Item.end(日期時間)進行過濾。這可能與Django的查詢呢?
Cat.objects.all().annotate(
item_count=Count('item'),
future_item_count=Count('item').filter(
end__gt=timezone.now())
).values(
'title',
'item_count',
'future_item_count'
)
# AttributeError: 'Count' object has no attribute 'filter'
我期望能獲得:[{'item_count': 2, 'future_item_count': 1, 'title': u'Cat 1'}]
我也試過RawSQL但缺少SQL技能:
from django.db.models.expressions import RawSQL
Cat.objects.all().annotate(
item_count=Count('item'),
future_item_count=RawSQL(
"""SELECT COUNT(*)
FROM project_item
JOIN project_item
AS foo
ON foo.cat_id = project_cat.id
WHERE project_item.end < NOW()""",
""
)).values(
'title',
'item_count',
'future_item_count'
)
# [{'item_count': 2, 'future_item_count': 2L, 'title': u'Cat 1'}]
但是,當我在WHERE project_item.end > NOW()"
改變WHERE project_item.end < NOW()"
我得到了相同的結果:
[{'item_count': 2, 'future_item_count': 2L, 'title': u'Cat 1'}]
如何格式化原始SQL?或者這可以通過Django查詢來完成嗎?
您無法過濾「計數」。您正在尋找'Case'表達式,查看[documentation](https://docs.djangoproject.com/en/1.9/ref/models/conditional-expressions/#case) – dnaranjo
@dnaranjo感謝您的建議。我確實讀過這部分文檔,但放棄了這個選項,因爲它在註釋中使用了'then'的值。也許我錯過了一些東西。雖然我接受了原始答案,但我仍然想知道如何做到這一點,而不會退回到原始SQL。 – allcaps