姜戈:哪几天有对象?
Django: Which days have objects?
我目前正在为我的一个 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
这 returns 我列出了所有有项目的日子。这是可行的,但是我正在寻找一种更有效的方法来执行此操作,因为 Django 正在为 .exists()
多次访问数据库
有什么建议吗?
首先,让我们获取所需月份的所有项目。
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
是 'almost' 等于 if not self.datetime
我看到两个可能的选择。第一个是在数据库级别添加计数,第二个是在 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 视图、仅包含一天的额外列等)
使用dates
方法。
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
我目前正在为我的一个 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
这 returns 我列出了所有有项目的日子。这是可行的,但是我正在寻找一种更有效的方法来执行此操作,因为 Django 正在为 .exists()
多次访问数据库有什么建议吗?
首先,让我们获取所需月份的所有项目。
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
是 'almost' 等于if not self.datetime
我看到两个可能的选择。第一个是在数据库级别添加计数,第二个是在 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 视图、仅包含一天的额外列等)
使用dates
方法。
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