Add nap averages data to the averages card.

This commit is contained in:
Christopher Charbonneau Wells 2017-11-04 17:52:28 -04:00
parent 4037f97e72
commit cb2c63cf8a
3 changed files with 107 additions and 36 deletions

View File

@ -8,6 +8,22 @@
<div class="card-body">
<div class="container">
<div class="row no-gutters text-center">
<div class="col-md-6 col-sm-3">
<div class="text-muted">Nap time</div>
{% if naps.average %}
{{ naps.average|duration_string:'m' }}
{% else %}
<em>Not enough data</em>
{% endif %}
</div>
<div class="col-md-6 col-sm-3">
<div class="text-muted">Naps/day</div>
{% if naps.avg_per_day %}
{{ naps.avg_per_day|floatformat }}
{% else %}
<em>Not enough data</em>
{% endif %}
</div>
<div class="col-md-6 col-sm-3 col-xs-12">
<div class="text-muted">Sleep time</div>
{% if sleep.average %}

View File

@ -12,10 +12,10 @@
{% block content %}
<div id="dashboard-child" class="row align-items-start">
<div class="col-lg-4 col-md-6 col-sm-12">
{% card_averages object %}
{% card_feeding_last object %}
{% card_feeding_last_method object %}
{% card_timer_list %}
{% card_averages object %}
</div>
<div class="col-lg-4 col-md-6 col-sm-12">
{% card_sleep_last object %}

View File

@ -2,7 +2,8 @@
from __future__ import unicode_literals
from django import template
from django.db.models import Sum
from django.db.models import Avg, Count, Sum
from django.db.models.functions import TruncDate
from django.utils import timezone
from core.models import DiaperChange, Feeding, Sleep, Timer, TummyTime
@ -18,6 +19,91 @@ def card_averages(child):
:param child: an instance of the Child model.
:returns: a dictionary of Diaper Change, Feeding and Sleep averages data.
"""
return {
'changes': _diaperchange_averages(child),
'feedings': _feeding_averages(child),
'naps': _nap_averages(child),
'sleep': _sleep_averages(child)}
def _diaperchange_averages(child):
"""
Averaged Diaper Change data.
:param child: an instance of the Child model.
:returns: a dictionary of Diaper Change averages data.
"""
instances = DiaperChange.objects.filter(child=child).order_by('time')
changes = {
'btwn_total': timezone.timedelta(0),
'btwn_count': instances.count() - 1,
'btwn_average': 0}
last_instance = None
for instance in instances:
if last_instance:
changes['btwn_total'] += instance.time - last_instance.time
last_instance = instance
if changes['btwn_count'] > 0:
changes['btwn_average'] = changes['btwn_total'] / changes['btwn_count']
return changes
def _feeding_averages(child):
"""
Averaged Feeding data.
:param child: an instance of the Child model.
:returns: a dictionary of Feeding averages data.
"""
instances = Feeding.objects.filter(child=child).order_by('start')
feedings = {
'btwn_total': timezone.timedelta(0),
'btwn_count': instances.count() - 1,
'btwn_average': 0}
last_instance = None
for instance in instances:
if last_instance:
feedings['btwn_total'] += instance.start - last_instance.end
last_instance = instance
if feedings['btwn_count'] > 0:
feedings['btwn_average'] = \
feedings['btwn_total'] / feedings['btwn_count']
return feedings
def _nap_averages(child):
"""
Averaged nap data.
:param child: an instance of the Child model.
:returns: a dictionary of nap (Sleep) averages data.
"""
instances = Sleep.naps.filter(child=child).order_by('start')
naps = {
'total': instances.aggregate(Sum('duration'))['duration__sum'],
'count': instances.count(),
'average': 0,
'avg_per_day': 0}
if naps['count'] > 0:
naps['average'] = naps['total'] / naps['count']
naps_avg = instances.annotate(date=TruncDate('start')).values('date') \
.annotate(naps_count=Count('id')).order_by() \
.aggregate(Avg('naps_count'))
naps['avg_per_day'] = naps_avg['naps_count__avg']
return naps
def _sleep_averages(child):
"""
Averaged Sleep data.
:param child: an instance of the Child model.
:returns: a dictionary of Sleep averages data.
"""
instances = Sleep.objects.filter(child=child).order_by('start')
sleep = {
'total': instances.aggregate(Sum('duration'))['duration__sum'],
@ -34,42 +120,11 @@ def card_averages(child):
last_instance = instance
if sleep['count'] > 0:
sleep['average'] = sleep['total']/sleep['count']
sleep['average'] = sleep['total'] / sleep['count']
if sleep['btwn_count'] > 0:
sleep['btwn_average'] = sleep['btwn_total']/sleep['btwn_count']
sleep['btwn_average'] = sleep['btwn_total'] / sleep['btwn_count']
instances = DiaperChange.objects.filter(child=child).order_by('time')
changes = {
'btwn_total': timezone.timedelta(0),
'btwn_count': instances.count() - 1,
'btwn_average': 0}
last_instance = None
for instance in instances:
if last_instance:
changes['btwn_total'] += instance.time - last_instance.time
last_instance = instance
if changes['btwn_count'] > 0:
changes['btwn_average'] = changes['btwn_total']/changes['btwn_count']
instances = Feeding.objects.filter(child=child).order_by('start')
feedings = {
'btwn_total': timezone.timedelta(0),
'btwn_count': instances.count() - 1,
'btwn_average': 0}
last_instance = None
for instance in instances:
if last_instance:
feedings['btwn_total'] += instance.start - last_instance.end
last_instance = instance
if feedings['btwn_count'] > 0:
feedings['btwn_average'] = \
feedings['btwn_total']/feedings['btwn_count']
return {'changes': changes, 'feedings': feedings, 'sleep': sleep}
return sleep
@register.inclusion_tag('cards/diaperchange_last.html')