对于简单的期刊应用,我有以下模型:
class Journal(models.Model):
title = models.CharField(max_length=50)
created_by = models.ForeignKey(User)
class Entry(models.Model):
journal = models.ForeignKey(Journal)
note = models.TextField()
date = models.DateField()
我想计算当前条纹:从今天开始,用户提交条目的连续天数。
我有以下函数(非常低效)来计算当前条纹:
def current_streak(journal):
count = 0
today = datetime.date.today()
date = today-datetime.timedelta(days=count)
while Entry.objects.filter(journal=journal, date=date).exists():
count += 1
date = today-datetime.timedelta(days=count)
return count
使用较少的数据库查询计算此值的更好方法是什么?
答案 0 :(得分:2)
执行此类操作的最佳方法是在一个SQL查询中获取所有日期(并确保Django ORM实际上通过一个SQL查询提取数据),然后处理该信息服务器端:
(请注意,此示例假定日期==今天的单项日记将是1的条纹。)
def current_streak(journal):
total_streak = 0
current_streak = 0
today = datetime.date.today()
compareDate = today + datetime.timedelta(1) # Tomorrow
# Using list() here pulls all the entries from the DB at once
# Gets all entry dates for this journal and whose dates are <= today
entry_dates = list(Entry.objects.values("date").filter(journal=journal, date__lte = today).order_by("-date"))
for date in entry_dates:
# Get the difference btw the dates
delta = compareDate - date
if delta.days == 1: # Keep the streak going!
current_streak += 1
elsif delta.days == 0: # Don't bother increasing the day if there's multiple ones on the same day
pass
else: # Awwww...
break # The current streak is done, exit the loop
compareDate = date
if current_streak > total_streak:
total_streak = current_streak
return total_streak
这里有关于Django ORM的一些信息,以及它何时实际从数据库中提取数据:https://docs.djangoproject.com/en/dev/topics/db/queries/#caching-and-querysets