Python Django:哪几天有对象?

Python Django:哪几天有对象?,python,django,calendar,Python,Django,Calendar,我目前正在为我的一个Django项目创建一个简单的日历。日历将显示当前月份和日期。任何有当天项目的日期都将以红色突出显示,以便用户知道当天有项目。物品的数量或它们是什么并不重要。我们关心的只是一天中是否有物品 假设我有以下模型 class Items(models.Model): name = models.CharField(max_length=140) datetime = models.DateTimeField(auto_now_add=False) def

我目前正在为我的一个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()多次访问DB


有什么建议吗?

首先,让我们获取所需月份的所有项目

items = Items.objects.filter(datetime__month=6, datetime__year=2015)
days = set([item.datetime.day for item in items]) # unique days
如果要进行部分查询,请指定所需的
,概念如下:

    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>)')
QUERY=u'从“主项目”中选择“主项目”。“添加日期”,其中
(django_datetime_摘录(\'month\',“主项”。“添加日期”,%s)=%s
和“主项”。“添加日期”介于%s和%s之间)
-参数=(u“'UTC'”,u'6',u'datetime.datetime(2015,1,1,0,0,tzinfo=),
u'datetime.datetime(2015,12,31,23,59,599999,tzinfo=))
如果您正在处理大量的
,您可以将查询分解为多个部分(例如
<15
=15
)。这将导致额外的数据库命中,但内存使用选择将更小。你也可以考虑不同的方法。 另请注意:

  • datetime
    不是字段的最佳名称。说出它的名字 有意思的是,比如:“添加日期”、“创建日期”或者类似的东西 那
  • 如果self.datetime为None
    则“几乎”等于
    如果不是self.datetime

    • 我看到两种可能的选择。第一个是在DB级别添加计数,第二个是在python级别对可用数据进行有效循环。根据数据大小和数据库效率,您可以选择最适合自己的

      数据库中的计数说明如下:

      或者解决方案二,一个简单的脚本(不是很优雅,但只是一个示例):

      我会坚持使用数据库解决方案,因为它可以进行优化(sql视图、仅包含一天的额外列等)

      使用该方法


      谢谢你的快速回复。我喜欢你的解决方案。这允许一次到DB的跳闸。但是如果物品数量巨大怎么办?为了它的缘故,假设这个月正好有50000件物品。所有这些都必须在设置操作期间存储在内存中。我不确定这会对事情产生什么影响,但这绝对是我可以尝试的。谢谢你。目前正在查看您提到的第一个建议。在分贝级计数是我最初想到的。让DB做所有繁重的工作可能是一条可行之路。
      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()
      
      items = Item.objects.filter(date_added__month=6, date_added__year=2015)
      dates = items.dates('date_added', 'day') # returns a queryset of datetimes
      days = [d.day for d in dates] # convert to a list of days