Django:哪几天有对象?

时间:2015-06-09 20:16:00

标签: python django calendar

我目前正在为我的一个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()

有什么建议吗?

3 个答案:

答案 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