我目前正在为我的一个Django项目创建一个简单的日历。日历将显示当前月份和日期。任何当天有项目的日子都将以红色突出显示,以便用户知道当天有项目。物品的数量或物品的数量并不重要。我们关心的是一天是否有物品。
假设我有以下型号。
class Items(models.Model):
name = models.CharField(max_length=140)
datetime = models.DateTimeField(auto_now_add=False)
def save(self, *args, **kwargs):
if datetim is None:
created = datetime.now()
super(Items, self).save()
以下是我目前查找哪些日期项目的逻辑:
from calendar import monthrange
# Find number of days for June 2015
num_days = monthrange(2015, 6)[1]
days_with_items = []
'''
Increase num_days by 1 so that the last day of the month
is included in the range
'''
num_days =+ 1
for day in range(0, num_days):
has_items = Items.objects.filter(datetime__day = day,
datetime__month = 6,
datetime__year = 2015).exists()
if has_items:
days_with_items.append(day)
return days_with_items
这会返回一个包含所有项目日期的列表。然而,我正在寻找一种更有效的方法来实现这一点,因为Django正在为数据库进行多次访问.exists()
有什么建议吗?
答案 0 :(得分:1)
我看到两种可能的选择。第一个是在DB级别添加计数,第二个是在python级别上对可用数据进行有效循环。根据数据大小和数据库效率,您可以选择最适合您的数据。
这里解释数据库中的计数: Django ORM, group by day
或解决方案二,一个简单的脚本(不那么优雅......但仅作为一个例子):
days_with_items_hash = {}
items = Items.objects.filter(
datetime__month = 6,
datetime__year = 2015
)
for item in items:
days_with_item_hash[item.datetime.day] = True
days_with_item = days_with_item_hash.keys()
我会坚持使用数据库解决方案,因为它可以进行优化(sql视图,只需一天的额外列等)
答案 1 :(得分:0)
首先,让我们获取所需月份的所有项目。
items = Items.objects.filter(datetime__month=6, datetime__year=2015)
days = set([item.datetime.day for item in items]) # unique days
如果您想进行部分查询,请指定您需要的values
,这是概念:
items = Item.objects.filter(
date_added__month=6, date_added__year=2015
).values('date_added')
days = set([item['date_added'].day for item in items])
这将导致以下SQL
查询:
QUERY = u'SELECT "main_item"."date_added" FROM "main_item" WHERE
(django_datetime_extract(\'month\', "main_item"."date_added", %s) = %s
AND "main_item"."date_added" BETWEEN %s AND %s)'
- PARAMS = (u"'UTC'", u'6', u'datetime.datetime(2015, 1, 1, 0, 0, tzinfo=<UTC>)',
u'datetime.datetime(2015, 12, 31, 23, 59, 59, 999999, tzinfo=<UTC>)')
如果您正在处理Items
的大量问题,则可以将查询分成若干部分(例如< 15
和>=15
)。这将导致额外的数据库命中,但内存使用选择将更小。您还可以考虑不同的方法。
请注意:
datetime
不是字段的最佳名称。说出来
有意义的,如:“date_added”,“date_created”或类似的东西
该if self.datetime is None
“几乎”等于if not self.datetime
答案 2 :(得分:0)
使用this link方法。
import turtle