mirror of https://github.com/snachodog/mybuddy.git
Add Height, Head Circumference, and BMI, corresponding reports, and move to separate menu with Weight and Temperature.
This commit is contained in:
parent
89ed408acc
commit
9b604627a1
|
@ -173,3 +173,18 @@ class WeightSerializer(CoreModelSerializer):
|
|||
class Meta:
|
||||
model = models.Weight
|
||||
fields = ('id', 'child', 'weight', 'date', 'notes')
|
||||
|
||||
class HeightSerializer(CoreModelSerializer):
|
||||
class Meta:
|
||||
model = models.Height
|
||||
fields = ('id', 'child', 'height', 'date', 'notes')
|
||||
|
||||
class HeadCircumferenceSerializer(CoreModelSerializer):
|
||||
class Meta:
|
||||
model = models.HeadCircumference
|
||||
fields = ('id', 'child', 'head_circumference', 'date', 'notes')
|
||||
|
||||
class BMISerializer(CoreModelSerializer):
|
||||
class Meta:
|
||||
model = models.BMI
|
||||
fields = ('id', 'child', 'bmi', 'date', 'notes')
|
|
@ -15,6 +15,9 @@ router.register(r'temperature', views.TemperatureViewSet)
|
|||
router.register(r'timers', views.TimerViewSet)
|
||||
router.register(r'tummy-times', views.TummyTimeViewSet)
|
||||
router.register(r'weight', views.WeightViewSet)
|
||||
router.register(r'height', views.HeightViewSet)
|
||||
router.register(r'head-circumference', views.HeadCircumferenceViewSet)
|
||||
router.register(r'bmi', views.BMIViewSet)
|
||||
|
||||
app_name = 'api'
|
||||
|
||||
|
|
15
api/views.py
15
api/views.py
|
@ -60,3 +60,18 @@ class WeightViewSet(viewsets.ModelViewSet):
|
|||
queryset = models.Weight.objects.all()
|
||||
serializer_class = serializers.WeightSerializer
|
||||
filterset_fields = ('child', 'date')
|
||||
|
||||
class HeightViewSet(viewsets.ModelViewSet):
|
||||
queryset = models.Height.objects.all()
|
||||
serializer_class = serializers.HeightSerializer
|
||||
filterset_fields = ('child', 'date')
|
||||
|
||||
class HeadCircumferenceViewSet(viewsets.ModelViewSet):
|
||||
queryset = models.HeadCircumference.objects.all()
|
||||
serializer_class = serializers.HeadCircumferenceSerializer
|
||||
filterset_fields = ('child', 'date')
|
||||
|
||||
class BMIViewSet(viewsets.ModelViewSet):
|
||||
queryset = models.BMI.objects.all()
|
||||
serializer_class = serializers.BMISerializer
|
||||
filterset_fields = ('child', 'date')
|
||||
|
|
|
@ -399,5 +399,68 @@
|
|||
"date": "2017-11-18",
|
||||
"notes": "before feed"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "core.height",
|
||||
"pk": 1,
|
||||
"fields":
|
||||
{
|
||||
"child": 1,
|
||||
"height": 9.5,
|
||||
"date": "2017-11-11"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "core.height",
|
||||
"pk": 2,
|
||||
"fields":
|
||||
{
|
||||
"child": 1,
|
||||
"height": 10.5,
|
||||
"date": "2017-11-18",
|
||||
"notes": "before feed"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "core.headcircumference",
|
||||
"pk": 1,
|
||||
"fields":
|
||||
{
|
||||
"child": 1,
|
||||
"head_circumference": 5.5,
|
||||
"date": "2017-11-11"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "core.headcircumference",
|
||||
"pk": 2,
|
||||
"fields":
|
||||
{
|
||||
"child": 1,
|
||||
"head_circumference": 6.5,
|
||||
"date": "2017-11-18",
|
||||
"notes": "before feed"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "core.bmi",
|
||||
"pk": 1,
|
||||
"fields":
|
||||
{
|
||||
"child": 1,
|
||||
"bmi": 25.5,
|
||||
"date": "2017-11-11"
|
||||
}
|
||||
},
|
||||
{
|
||||
"model": "core.bmi",
|
||||
"pk": 2,
|
||||
"fields":
|
||||
{
|
||||
"child": 1,
|
||||
"bmi": 26.5,
|
||||
"date": "2017-11-18",
|
||||
"notes": "before feed"
|
||||
}
|
||||
}
|
||||
]
|
|
@ -249,3 +249,60 @@ class Command(BaseCommand):
|
|||
date=self.time.date(),
|
||||
notes=notes
|
||||
).save()
|
||||
|
||||
@transaction.atomic
|
||||
def _add_height_entry(self):
|
||||
"""
|
||||
Add a height entry. This assumes a weekly interval.
|
||||
:returns:
|
||||
"""
|
||||
self.height += uniform(0.1, 0.3)
|
||||
|
||||
notes = ''
|
||||
if choice([True, False, False, False]):
|
||||
notes = ' '.join(self.faker.sentences(randint(1, 5)))
|
||||
|
||||
models.Height.objects.create(
|
||||
child=self.child,
|
||||
height=round(self.height, 2),
|
||||
date=self.time.date(),
|
||||
notes=notes
|
||||
).save()
|
||||
|
||||
@transaction.atomic
|
||||
def _add_head_circumference_entry(self):
|
||||
"""
|
||||
Add a head circumference entry. This assumes a weekly interval.
|
||||
:returns:
|
||||
"""
|
||||
self.head_circumference += uniform(0.1, 0.3)
|
||||
|
||||
notes = ''
|
||||
if choice([True, False, False, False]):
|
||||
notes = ' '.join(self.faker.sentences(randint(1, 5)))
|
||||
|
||||
models.HeadCircumference.objects.create(
|
||||
child=self.child,
|
||||
head_circumference=round(self.head_circumference, 2),
|
||||
date=self.time.date(),
|
||||
notes=notes
|
||||
).save()
|
||||
|
||||
@transaction.atomic
|
||||
def _add_bmi_entry(self):
|
||||
"""
|
||||
Add a BMI entry. This assumes a weekly interval.
|
||||
:returns:
|
||||
"""
|
||||
self.bmi += uniform(0.1, 0.3)
|
||||
|
||||
notes = ''
|
||||
if choice([True, False, False, False]):
|
||||
notes = ' '.join(self.faker.sentences(randint(1, 5)))
|
||||
|
||||
models.bmi.objects.create(
|
||||
child=self.child,
|
||||
bmi=round(self.bmi, 2),
|
||||
date=self.time.date(),
|
||||
notes=notes
|
||||
).save()
|
||||
|
|
|
@ -221,6 +221,30 @@
|
|||
"css": "cancel",
|
||||
"code": 59411,
|
||||
"src": "fontawesome"
|
||||
},
|
||||
{
|
||||
"uid": "6a96c51e961a2e48dfcbe2c47fd1204e",
|
||||
"css": "height",
|
||||
"code": 61508,
|
||||
"src": "mfglabs"
|
||||
},
|
||||
{
|
||||
"uid": "bb46b15cb78cc4cc05d3d715d522ac4d",
|
||||
"css": "head-circumference",
|
||||
"code": 59412,
|
||||
"src": "entypo"
|
||||
},
|
||||
{
|
||||
"uid": "2c452255d4fed51ef0a6ef86436a7d08",
|
||||
"css": "bmi",
|
||||
"code": 62101,
|
||||
"src": "fontawesome"
|
||||
},
|
||||
{
|
||||
"uid": "b95cfc96d48a72dd665e0ab109880b5e",
|
||||
"css": "measurements",
|
||||
"code": 59413,
|
||||
"src": "entypo"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -19,6 +19,9 @@
|
|||
.icon-arrow-up:before { content: '\e811'; } /* '' */
|
||||
.icon-arrow-down:before { content: '\e812'; } /* '' */
|
||||
.icon-cancel:before { content: '\e813'; } /* '' */
|
||||
.icon-head-circumference:before { content: '\e814'; } /* '' */
|
||||
.icon-measurements:before { content: '\e815'; } /* '' */
|
||||
.icon-height:before { content: '\f044'; } /* '' */
|
||||
.icon-dashboard:before { content: '\f0e4'; } /* '' */
|
||||
.icon-tummytime:before { content: '\f118'; } /* '' */
|
||||
.icon-sad:before { content: '\f119'; } /* '' */
|
||||
|
@ -34,4 +37,5 @@
|
|||
.icon-note:before { content: '\f249'; } /* '' */
|
||||
.icon-weight:before { content: '\f24e'; } /* '' */
|
||||
.icon-today:before { content: '\f274'; } /* '' */
|
||||
.icon-bmi:before { content: '\f295'; } /* '' */
|
||||
.icon-temperature:before { content: '\f2c8'; } /* '' */
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -19,6 +19,9 @@
|
|||
.icon-arrow-up { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-arrow-down { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-cancel { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-head-circumference { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-measurements { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-height { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-dashboard { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-tummytime { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-sad { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
|
@ -34,4 +37,5 @@
|
|||
.icon-note { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-weight { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-today { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-bmi { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-temperature { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
|
|
|
@ -30,6 +30,9 @@
|
|||
.icon-arrow-up { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-arrow-down { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-cancel { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-head-circumference { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-measurements { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-height { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-dashboard { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-tummytime { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-sad { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
|
@ -45,4 +48,5 @@
|
|||
.icon-note { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-weight { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-today { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-bmi { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-temperature { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
@font-face {
|
||||
font-family: 'babybuddy';
|
||||
src: url('../font/babybuddy.eot?72731680');
|
||||
src: url('../font/babybuddy.eot?72731680#iefix') format('embedded-opentype'),
|
||||
url('../font/babybuddy.woff2?72731680') format('woff2'),
|
||||
url('../font/babybuddy.woff?72731680') format('woff'),
|
||||
url('../font/babybuddy.ttf?72731680') format('truetype'),
|
||||
url('../font/babybuddy.svg?72731680#babybuddy') format('svg');
|
||||
src: url('../font/babybuddy.eot?3615871');
|
||||
src: url('../font/babybuddy.eot?3615871#iefix') format('embedded-opentype'),
|
||||
url('../font/babybuddy.woff2?3615871') format('woff2'),
|
||||
url('../font/babybuddy.woff?3615871') format('woff'),
|
||||
url('../font/babybuddy.ttf?3615871') format('truetype'),
|
||||
url('../font/babybuddy.svg?3615871#babybuddy') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
|||
@media screen and (-webkit-min-device-pixel-ratio:0) {
|
||||
@font-face {
|
||||
font-family: 'babybuddy';
|
||||
src: url('../font/babybuddy.svg?72731680#babybuddy') format('svg');
|
||||
src: url('../font/babybuddy.svg?3615871#babybuddy') format('svg');
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
@ -74,6 +74,9 @@
|
|||
.icon-arrow-up:before { content: '\e811'; } /* '' */
|
||||
.icon-arrow-down:before { content: '\e812'; } /* '' */
|
||||
.icon-cancel:before { content: '\e813'; } /* '' */
|
||||
.icon-head-circumference:before { content: '\e814'; } /* '' */
|
||||
.icon-measurements:before { content: '\e815'; } /* '' */
|
||||
.icon-height:before { content: '\f044'; } /* '' */
|
||||
.icon-dashboard:before { content: '\f0e4'; } /* '' */
|
||||
.icon-tummytime:before { content: '\f118'; } /* '' */
|
||||
.icon-sad:before { content: '\f119'; } /* '' */
|
||||
|
@ -89,4 +92,5 @@
|
|||
.icon-note:before { content: '\f249'; } /* '' */
|
||||
.icon-weight:before { content: '\f24e'; } /* '' */
|
||||
.icon-today:before { content: '\f274'; } /* '' */
|
||||
.icon-bmi:before { content: '\f295'; } /* '' */
|
||||
.icon-temperature:before { content: '\f2c8'; } /* '' */
|
||||
|
|
|
@ -146,11 +146,11 @@
|
|||
}
|
||||
@font-face {
|
||||
font-family: 'babybuddy';
|
||||
src: url('./font/babybuddy.eot?3175326');
|
||||
src: url('./font/babybuddy.eot?3175326#iefix') format('embedded-opentype'),
|
||||
url('./font/babybuddy.woff?3175326') format('woff'),
|
||||
url('./font/babybuddy.ttf?3175326') format('truetype'),
|
||||
url('./font/babybuddy.svg?3175326#babybuddy') format('svg');
|
||||
src: url('./font/babybuddy.eot?20083249');
|
||||
src: url('./font/babybuddy.eot?20083249#iefix') format('embedded-opentype'),
|
||||
url('./font/babybuddy.woff?20083249') format('woff'),
|
||||
url('./font/babybuddy.ttf?20083249') format('truetype'),
|
||||
url('./font/babybuddy.svg?20083249#babybuddy') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
@ -281,9 +281,20 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="span3" title="Code: 0xe814">
|
||||
<i class="demo-icon icon-head-circumference"></i> <span class="i-name">icon-head-circumference</span><span class="i-code">0xe814</span>
|
||||
</div>
|
||||
<div class="span3" title="Code: 0xe815">
|
||||
<i class="demo-icon icon-measurements"></i> <span class="i-name">icon-measurements</span><span class="i-code">0xe815</span>
|
||||
</div>
|
||||
<div class="span3" title="Code: 0xf044">
|
||||
<i class="demo-icon icon-height"></i> <span class="i-name">icon-height</span><span class="i-code">0xf044</span>
|
||||
</div>
|
||||
<div class="span3" title="Code: 0xf0e4">
|
||||
<i class="demo-icon icon-dashboard"></i> <span class="i-name">icon-dashboard</span><span class="i-code">0xf0e4</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="span3" title="Code: 0xf118">
|
||||
<i class="demo-icon icon-tummytime"></i> <span class="i-name">icon-tummytime</span><span class="i-code">0xf118</span>
|
||||
</div>
|
||||
|
@ -293,11 +304,11 @@
|
|||
<div class="span3" title="Code: 0xf126">
|
||||
<i class="demo-icon icon-source"></i> <span class="i-name">icon-source</span><span class="i-code">0xf126</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="span3" title="Code: 0xf137">
|
||||
<i class="demo-icon icon-angle-circled-left"></i> <span class="i-name">icon-angle-circled-left</span><span class="i-code">0xf137</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="span3" title="Code: 0xf138">
|
||||
<i class="demo-icon icon-angle-circled-right"></i> <span class="i-name">icon-angle-circled-right</span><span class="i-code">0xf138</span>
|
||||
</div>
|
||||
|
@ -307,11 +318,11 @@
|
|||
<div class="span3" title="Code: 0xf1b1">
|
||||
<i class="demo-icon icon-feeding"></i> <span class="i-name">icon-feeding</span><span class="i-code">0xf1b1</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="span3" title="Code: 0xf1b3">
|
||||
<i class="demo-icon icon-activities"></i> <span class="i-name">icon-activities</span><span class="i-code">0xf1b3</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="span3" title="Code: 0xf1da">
|
||||
<i class="demo-icon icon-timeline"></i> <span class="i-name">icon-timeline</span><span class="i-code">0xf1da</span>
|
||||
</div>
|
||||
|
@ -321,17 +332,20 @@
|
|||
<div class="span3" title="Code: 0xf236">
|
||||
<i class="demo-icon icon-sleep"></i> <span class="i-name">icon-sleep</span><span class="i-code">0xf236</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="span3" title="Code: 0xf249">
|
||||
<i class="demo-icon icon-note"></i> <span class="i-name">icon-note</span><span class="i-code">0xf249</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="span3" title="Code: 0xf24e">
|
||||
<i class="demo-icon icon-weight"></i> <span class="i-name">icon-weight</span><span class="i-code">0xf24e</span>
|
||||
</div>
|
||||
<div class="span3" title="Code: 0xf274">
|
||||
<i class="demo-icon icon-today"></i> <span class="i-name">icon-today</span><span class="i-code">0xf274</span>
|
||||
</div>
|
||||
<div class="span3" title="Code: 0xf295">
|
||||
<i class="demo-icon icon-bmi"></i> <span class="i-name">icon-bmi</span><span class="i-code">0xf295</span>
|
||||
</div>
|
||||
<div class="span3" title="Code: 0xf2c8">
|
||||
<i class="demo-icon icon-temperature"></i> <span class="i-name">icon-temperature</span><span class="i-code">0xf2c8</span>
|
||||
</div>
|
||||
|
|
Binary file not shown.
|
@ -46,6 +46,12 @@
|
|||
|
||||
<glyph glyph-name="cancel" unicode="" d="M724 112q0-22-15-38l-76-76q-16-15-38-15t-38 15l-164 165-164-165q-16-15-38-15t-38 15l-76 76q-16 16-16 38t16 38l164 164-164 164q-16 16-16 38t16 38l76 76q16 16 38 16t38-16l164-164 164 164q16 16 38 16t38-16l76-76q15-15 15-38t-15-38l-164-164 164-164q15-15 15-38z" horiz-adv-x="785.7" />
|
||||
|
||||
<glyph glyph-name="head-circumference" unicode="" d="M408 760q168 0 287-116t123-282l122 0-184-206-184 206 144 0q-4 124-94 210t-214 86q-126 0-216-90t-90-218q0-126 90-216t216-90q104 0 182 60l70-76q-110-88-252-88-168 0-288 120t-120 290 120 290 288 120z" horiz-adv-x="940" />
|
||||
|
||||
<glyph glyph-name="measurements" unicode="" d="M630 750q28 0 49-21t21-49l0-760q0-30-21-50t-49-20l-560 0q-28 0-49 20t-21 50l0 760q0 28 21 49t49 21l60-150 440 0z m-100-100l-360 0-44 100 108 0 36 100 160 0 36-100 110 0z" horiz-adv-x="700" />
|
||||
|
||||
<glyph glyph-name="height" unicode="" d="M0 144q0-31 22-54l180-180q20-20 46-22t50 12l-96 96 41 41 97-97 42 41-98 97 41 41 97-96 42 40-97 98 40 40 98-96 39 39-98 96 42 42 97-97 41 41-97 97 41 41 97-97 41 41-97 97 41 41 97-97 41 41-97 98 41 40 98-97 41 42-98 97 41 41 96-95q13 22 10 48t-21 45l-180 180q-23 22-54 22t-55-23l-589-590q-23-22-23-54z" horiz-adv-x="922.9" />
|
||||
|
||||
<glyph glyph-name="dashboard" unicode="" d="M214 207q0 30-21 51t-50 21-51-21-21-51 21-50 51-21 50 21 21 50z m107 250q0 30-20 51t-51 21-50-21-21-51 21-50 50-21 51 21 20 50z m239-268l57 213q3 14-5 27t-21 16-27-3-17-22l-56-213q-33-3-60-25t-35-55q-11-43 11-81t66-50 81 11 50 66q9 33-4 65t-40 51z m369 18q0 30-21 51t-51 21-50-21-21-51 21-50 50-21 51 21 21 50z m-358 357q0 30-20 51t-51 21-50-21-21-51 21-50 50-21 51 21 20 50z m250-107q0 30-20 51t-51 21-50-21-21-51 21-50 50-21 51 21 20 50z m179-250q0-145-79-269-10-17-30-17h-782q-20 0-30 17-79 123-79 269 0 102 40 194t106 160 160 107 194 39 194-39 160-107 106-160 40-194z" horiz-adv-x="1000" />
|
||||
|
||||
<glyph glyph-name="tummytime" unicode="" d="M633 250q-21-67-77-109t-127-41-128 41-77 109q-4 14 3 27t21 18q14 4 27-2t17-22q14-44 52-72t85-28 84 28 52 72q4 15 18 22t27 2 21-18 2-27z m-276 243q0-30-21-51t-50-21-51 21-21 51 21 50 51 21 50-21 21-50z m286 0q0-30-21-51t-51-21-50 21-21 51 21 50 50 21 51-21 21-50z m143-143q0 73-29 139t-76 114-114 76-138 28-139-28-114-76-76-114-29-139 29-139 76-113 114-77 139-28 138 28 114 77 76 113 29 139z m71 0q0-117-57-215t-156-156-215-58-216 58-155 156-58 215 58 215 155 156 216 58 215-58 156-156 57-215z" horiz-adv-x="857.1" />
|
||||
|
@ -76,6 +82,8 @@
|
|||
|
||||
<glyph glyph-name="today" unicode="" d="M727 312l-286-286q-5-5-12-5t-13 5l-161 161q-5 6-5 13t5 12l26 26q5 5 12 5t13-5l123-123 247 248q6 5 13 5t13-5l25-26q5-5 5-12t-5-13z m-656-391h786v572h-786v-572z m215 679v161q0 8-5 13t-13 5h-36q-8 0-13-5t-5-13v-161q0-8 5-13t13-5h36q8 0 13 5t5 13z m428 0v161q0 8-5 13t-13 5h-35q-8 0-13-5t-5-13v-161q0-8 5-13t13-5h35q8 0 13 5t5 13z m215 36v-715q0-29-22-50t-50-21h-786q-29 0-50 21t-21 50v715q0 29 21 50t50 21h72v54q0 37 26 63t63 26h36q37 0 63-26t26-63v-54h214v54q0 37 27 63t63 26h35q37 0 64-26t26-63v-54h71q29 0 50-21t22-50z" horiz-adv-x="1000" />
|
||||
|
||||
<glyph glyph-name="bmi" unicode="" d="M714 136q0 29-21 50t-50 21-50-21-22-50 22-50 50-22 50 22 21 50z m-428 428q0 29-21 51t-51 21-50-21-21-51 21-50 50-21 51 21 21 50z m571-428q0-89-63-152t-151-63-152 63-62 152 62 151 152 63 151-63 63-151z m-53 607q0-11-8-21l-589-786q-11-15-28-15h-90q-14 0-25 11t-10 25q0 11 7 21l589 786q11 15 29 15h89q14 0 25-11t11-25z m-375-179q0-88-63-151t-152-63-151 63-63 151 63 152 151 63 152-63 63-152z" horiz-adv-x="857.1" />
|
||||
|
||||
<glyph glyph-name="temperature" unicode="" d="M357 100q0-45-31-76t-76-31-76 31-31 76q0 34 19 61t52 40v363h72v-363q32-12 52-40t19-61z m72 0q0 43-19 80t-53 63v428q0 45-31 76t-76 32-76-32-31-76v-428q-34-25-53-63t-19-80q0-74 53-126t126-53 126 53 53 126z m71 0q0-103-73-177t-177-73-177 73-73 177q0 102 71 175v396q0 75 53 127t126 52 126-52 53-127v-396q71-73 71-175z m71 321v-71h-107v71h107z m0 143v-71h-107v71h107z m0 143v-71h-107v71h107z" horiz-adv-x="571.4" />
|
||||
</font>
|
||||
</defs>
|
||||
|
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 18 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -151,6 +151,20 @@
|
|||
</a>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="nav-item dropdown">
|
||||
<a id="nav-measurements-menu-link"
|
||||
class="nav-link dropdown-toggle"
|
||||
href="#"
|
||||
data-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"><i class="icon-measurements" aria-hidden="true"></i>
|
||||
{% trans "Measurements" %}
|
||||
</a>
|
||||
<div class="dropdown-menu" aria-labelledby="nav-measurements-menu-link">
|
||||
|
||||
{% if perms.core.view_temperature %}
|
||||
<a class="dropdown-item{% if request.path == '/temperature/' %} active{% endif %}"
|
||||
href="{% url 'core:temperature-list' %}">
|
||||
|
@ -179,6 +193,48 @@
|
|||
</a>
|
||||
{% endif %}
|
||||
|
||||
{% if perms.core.view_height %}
|
||||
<a class="dropdown-item{% if request.path == '/height/' %} active{% endif %}"
|
||||
href="{% url 'core:height-list' %}">
|
||||
<i class="icon-height" aria-hidden="true"></i>
|
||||
{% trans "Height" %}
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if perms.core.add_height %}
|
||||
<a class="dropdown-item pl-5{% if request.path == '/height/add/' %} active{% endif %}"
|
||||
href="{% url 'core:height-add' %}"><i class="icon-add" aria-hidden="true"></i>
|
||||
{% trans "Height entry" %}
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
{% if perms.core.view_head_circumference %}
|
||||
<a class="dropdown-item{% if request.path == '/head-circumference/' %} active{% endif %}"
|
||||
href="{% url 'core:head-circumference-list' %}">
|
||||
<i class="icon-head-circumference aria-hidden="true"></i>
|
||||
{% trans "Head Circumference" %}
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if perms.core.add_head_circumference %}
|
||||
<a class="dropdown-item pl-5{% if request.path == '/head-circumference/add/' %} active{% endif %}"
|
||||
href="{% url 'core:head-circumference-add' %}"><i class="icon-add" aria-hidden="true"></i>
|
||||
{% trans "Head Circumference entry" %}
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
{% if perms.core.view_bmi %}
|
||||
<a class="dropdown-item{% if request.path == '/bmi/' %} active{% endif %}"
|
||||
href="{% url 'core:bmi-list' %}">
|
||||
<i class="icon-bmi" aria-hidden="true"></i>
|
||||
{% trans "BMI" %}
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if perms.core.add_bmi %}
|
||||
<a class="dropdown-item pl-5{% if request.path == '/bmi/add/' %} active{% endif %}"
|
||||
href="{% url 'core:bmi-add' %}"><i class="icon-add" aria-hidden="true"></i>
|
||||
{% trans "BMI entry" %}
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
</li>
|
||||
|
||||
|
|
|
@ -241,3 +241,39 @@ class WeightForm(CoreModelForm):
|
|||
}),
|
||||
'notes': forms.Textarea(attrs={'rows': 5}),
|
||||
}
|
||||
|
||||
class HeightForm(CoreModelForm):
|
||||
class Meta:
|
||||
model = models.Height
|
||||
fields = ['child', 'height', 'date', 'notes']
|
||||
widgets = {
|
||||
'date': forms.DateInput(attrs={
|
||||
'autocomplete': 'off',
|
||||
'data-target': '#datetimepicker_date',
|
||||
}),
|
||||
'notes': forms.Textarea(attrs={'rows': 5}),
|
||||
}
|
||||
|
||||
class HeadCircumferenceForm(CoreModelForm):
|
||||
class Meta:
|
||||
model = models.HeadCircumference
|
||||
fields = ['child', 'head_circumference', 'date', 'notes']
|
||||
widgets = {
|
||||
'date': forms.DateInput(attrs={
|
||||
'autocomplete': 'off',
|
||||
'data-target': '#datetimepicker_date',
|
||||
}),
|
||||
'notes': forms.Textarea(attrs={'rows': 5}),
|
||||
}
|
||||
|
||||
class BMIForm(CoreModelForm):
|
||||
class Meta:
|
||||
model = models.BMI
|
||||
fields = ['child', 'bmi', 'date', 'notes']
|
||||
widgets = {
|
||||
'date': forms.DateInput(attrs={
|
||||
'autocomplete': 'off',
|
||||
'data-target': '#datetimepicker_date',
|
||||
}),
|
||||
'notes': forms.Textarea(attrs={'rows': 5}),
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
# Generated by Django 3.2.10 on 2021-12-29 05:23
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('core', '0016_alter_sleep_napping'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Height',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('height', models.FloatField(verbose_name='Height')),
|
||||
('date', models.DateField(verbose_name='Date')),
|
||||
('notes', models.TextField(blank=True, null=True, verbose_name='Notes')),
|
||||
('child', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='height', to='core.child', verbose_name='Child')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Height',
|
||||
'verbose_name_plural': 'Height',
|
||||
'ordering': ['-date'],
|
||||
'default_permissions': ('view', 'add', 'change', 'delete'),
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='HeadCircumference',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('head_circumference', models.FloatField(verbose_name='Head Circumference')),
|
||||
('date', models.DateField(verbose_name='Date')),
|
||||
('notes', models.TextField(blank=True, null=True, verbose_name='Notes')),
|
||||
('child', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='head_circumference', to='core.child', verbose_name='Child')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Head Circumference',
|
||||
'verbose_name_plural': 'Head Circumference',
|
||||
'ordering': ['-date'],
|
||||
'default_permissions': ('view', 'add', 'change', 'delete'),
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='BMI',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('bmi', models.FloatField(verbose_name='BMI')),
|
||||
('date', models.DateField(verbose_name='Date')),
|
||||
('notes', models.TextField(blank=True, null=True, verbose_name='Notes')),
|
||||
('child', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='bmi', to='core.child', verbose_name='Child')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'BMI',
|
||||
'verbose_name_plural': 'BMI',
|
||||
'ordering': ['-date'],
|
||||
'default_permissions': ('view', 'add', 'change', 'delete'),
|
||||
},
|
||||
),
|
||||
]
|
102
core/models.py
102
core/models.py
|
@ -591,3 +591,105 @@ class Weight(models.Model):
|
|||
|
||||
def clean(self):
|
||||
validate_date(self.date, 'date')
|
||||
|
||||
class Height(models.Model):
|
||||
model_name = 'height'
|
||||
child = models.ForeignKey(
|
||||
'Child',
|
||||
on_delete=models.CASCADE,
|
||||
related_name='height',
|
||||
verbose_name=_('Child')
|
||||
)
|
||||
height = models.FloatField(
|
||||
blank=False,
|
||||
null=False,
|
||||
verbose_name=_('Height')
|
||||
)
|
||||
date = models.DateField(
|
||||
blank=False,
|
||||
null=False,
|
||||
verbose_name=_('Date')
|
||||
)
|
||||
notes = models.TextField(blank=True, null=True, verbose_name=_('Notes'))
|
||||
|
||||
objects = models.Manager()
|
||||
|
||||
class Meta:
|
||||
default_permissions = ('view', 'add', 'change', 'delete')
|
||||
ordering = ['-date']
|
||||
verbose_name = _('Height')
|
||||
verbose_name_plural = _('Height')
|
||||
|
||||
def __str__(self):
|
||||
return str(_('Height'))
|
||||
|
||||
def clean(self):
|
||||
validate_date(self.date, 'date')
|
||||
|
||||
class HeadCircumference(models.Model):
|
||||
model_name = 'head_circumference'
|
||||
child = models.ForeignKey(
|
||||
'Child',
|
||||
on_delete=models.CASCADE,
|
||||
related_name='head_circumference',
|
||||
verbose_name=_('Child')
|
||||
)
|
||||
head_circumference = models.FloatField(
|
||||
blank=False,
|
||||
null=False,
|
||||
verbose_name=_('Head Circumference')
|
||||
)
|
||||
date = models.DateField(
|
||||
blank=False,
|
||||
null=False,
|
||||
verbose_name=_('Date')
|
||||
)
|
||||
notes = models.TextField(blank=True, null=True, verbose_name=_('Notes'))
|
||||
|
||||
objects = models.Manager()
|
||||
|
||||
class Meta:
|
||||
default_permissions = ('view', 'add', 'change', 'delete')
|
||||
ordering = ['-date']
|
||||
verbose_name = _('Head Circumference')
|
||||
verbose_name_plural = _('Head Circumference')
|
||||
|
||||
def __str__(self):
|
||||
return str(_('Head Circumference'))
|
||||
|
||||
def clean(self):
|
||||
validate_date(self.date, 'date')
|
||||
|
||||
class BMI(models.Model):
|
||||
model_name = 'bmi'
|
||||
child = models.ForeignKey(
|
||||
'Child',
|
||||
on_delete=models.CASCADE,
|
||||
related_name='bmi',
|
||||
verbose_name=_('Child')
|
||||
)
|
||||
bmi = models.FloatField(
|
||||
blank=False,
|
||||
null=False,
|
||||
verbose_name=_('BMI')
|
||||
)
|
||||
date = models.DateField(
|
||||
blank=False,
|
||||
null=False,
|
||||
verbose_name=_('Date')
|
||||
)
|
||||
notes = models.TextField(blank=True, null=True, verbose_name=_('Notes'))
|
||||
|
||||
objects = models.Manager()
|
||||
|
||||
class Meta:
|
||||
default_permissions = ('view', 'add', 'change', 'delete')
|
||||
ordering = ['-date']
|
||||
verbose_name = _('BMI')
|
||||
verbose_name_plural = _('BMI')
|
||||
|
||||
def __str__(self):
|
||||
return str(_('BMI'))
|
||||
|
||||
def clean(self):
|
||||
validate_date(self.date, 'date')
|
|
@ -0,0 +1,20 @@
|
|||
{% extends 'babybuddy/page.html' %}
|
||||
{% load i18n widget_tweaks %}
|
||||
|
||||
{% block title %}{% trans "Delete a BMI Entry" %}{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<li class="breadcrumb-item"><a href="{% url 'core:bmi-list' %}">{% trans "BMI" %}</a></li>
|
||||
<li class="breadcrumb-item active" aria-current="page">{% trans "Delete" %}</li>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<form role="form" method="post">
|
||||
{% csrf_token %}
|
||||
{% blocktrans trimmed %}
|
||||
<h1>Are you sure you want to delete <span class="text-info">{{ object }}</span>?</h1>
|
||||
{% endblocktrans %}
|
||||
<input type="submit" value="{% trans "Delete" %}" class="btn btn-danger" />
|
||||
<a href="{% url 'core:bmi-list' %}" class="btn btn-default">{% trans "Cancel" %}</a>
|
||||
</form>
|
||||
{% endblock %}
|
|
@ -0,0 +1,39 @@
|
|||
{% extends 'babybuddy/page.html' %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}
|
||||
{% if object %}
|
||||
{{ object }}
|
||||
{% else %}
|
||||
{% trans "Add a BMI Entry" %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<li class="breadcrumb-item"><a href="{% url 'core:bmi-list' %}">{% trans "BMI" %}</a></li>
|
||||
{% if object %}
|
||||
<li class="breadcrumb-item active" aria-current="page">{% trans "Update" %}</li>
|
||||
{% else %}
|
||||
<li class="breadcrumb-item active" aria-current="page">{% trans "Add a BMI Entry" %}</li>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% if object %}
|
||||
{% blocktrans trimmed %}
|
||||
<h1>Update <span class="text-info">{{ object }}</span></h1>
|
||||
{% endblocktrans %}
|
||||
{% else %}
|
||||
<h1>{% trans "Add a BMI Entry" %}</h1>
|
||||
{% endif %}
|
||||
{% include 'babybuddy/form.html' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block javascript %}
|
||||
<script type="text/javascript">
|
||||
BabyBuddy.DatetimePicker.init($('#datetimepicker_date'), {
|
||||
format: 'L',
|
||||
extraFormats: ['YYYY-MM-DD']
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
|
@ -0,0 +1,73 @@
|
|||
{% extends 'babybuddy/page.html' %}
|
||||
{% load i18n widget_tweaks %}
|
||||
|
||||
{% block title %}{% trans "BMI" %}{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<li class="breadcrumb-item active" aria-current="page">{% trans "BMI" %}</li>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>
|
||||
{% trans "BMI" %}
|
||||
{% if perms.core.add_bmi %}
|
||||
<a href="{% url 'core:bmi-add' %}" class="btn btn-sm btn-success">
|
||||
<i class="icon-bmi" aria-hidden="true"></i> {% trans "Add BMI" %}
|
||||
</a>
|
||||
{% endif %}
|
||||
</h1>
|
||||
{% include 'babybuddy/filter.html' %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-instances">
|
||||
<thead class="thead-inverse">
|
||||
<tr>
|
||||
<th>{% trans "Actions" %}</th>
|
||||
<th>{% trans "Date" %}</th>
|
||||
{% if not unique_child %}
|
||||
<th>{% trans "Child" %}</th>
|
||||
{% endif %}
|
||||
<th>{% trans "BMI" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for bmi in object_list %}
|
||||
{% cycle "odd" "even" as row_class silent %}
|
||||
<tr class="{{ row_class }}">
|
||||
<td>
|
||||
<div class="btn-group btn-group-sm" role="group" aria-label="{% trans "Actions" %}">
|
||||
|
||||
{% if perms.core.change_bmi %}
|
||||
<a href="{% url 'core:bmi-update' bmi.id %}" class="btn btn-primary">
|
||||
<i class="icon-update" aria-hidden="true"></i>
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
{% if perms.core.delete_bmi %}
|
||||
<a href="{% url 'core:bmi-delete' bmi.id %}" class="btn btn-danger">
|
||||
<i class="icon-delete" aria-hidden="true"></i>
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
</td>
|
||||
<th scope="row">{{ bmi.date }}</th>
|
||||
{% if not unique_child %}
|
||||
<td><a href="{% url 'core:child' bmi.child.slug %}">{{ bmi.child }}</a></td>
|
||||
{% endif %}
|
||||
<td>{{ bmi.bmi }}</td>
|
||||
</tr>
|
||||
{% if bmi.notes %}
|
||||
<tr class="{{ row_class }} row-details">
|
||||
<td colspan="4"><i class="icon-note mr-2" aria-hidden="true"></i>{{ bmi.notes }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% empty %}
|
||||
<tr>
|
||||
<th colspan="4">{% trans "No bmi entries found." %}</th>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% include 'babybuddy/paginator.html' %}
|
||||
{% endblock %}
|
|
@ -0,0 +1,20 @@
|
|||
{% extends 'babybuddy/page.html' %}
|
||||
{% load i18n widget_tweaks %}
|
||||
|
||||
{% block title %}{% trans "Delete a Head Circumference Entry" %}{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<li class="breadcrumb-item"><a href="{% url 'core:head-circumference-list' %}">{% trans "Head Circumference" %}</a></li>
|
||||
<li class="breadcrumb-item active" aria-current="page">{% trans "Delete" %}</li>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<form role="form" method="post">
|
||||
{% csrf_token %}
|
||||
{% blocktrans trimmed %}
|
||||
<h1>Are you sure you want to delete <span class="text-info">{{ object }}</span>?</h1>
|
||||
{% endblocktrans %}
|
||||
<input type="submit" value="{% trans "Delete" %}" class="btn btn-danger" />
|
||||
<a href="{% url 'core:head-circumference-list' %}" class="btn btn-default">{% trans "Cancel" %}</a>
|
||||
</form>
|
||||
{% endblock %}
|
|
@ -0,0 +1,39 @@
|
|||
{% extends 'babybuddy/page.html' %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}
|
||||
{% if object %}
|
||||
{{ object }}
|
||||
{% else %}
|
||||
{% trans "Add a Head Circumference Entry" %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<li class="breadcrumb-item"><a href="{% url 'core:head-circumference-list' %}">{% trans "Head Circumference" %}</a></li>
|
||||
{% if object %}
|
||||
<li class="breadcrumb-item active" aria-current="page">{% trans "Update" %}</li>
|
||||
{% else %}
|
||||
<li class="breadcrumb-item active" aria-current="page">{% trans "Add a Head Circumference Entry" %}</li>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% if object %}
|
||||
{% blocktrans trimmed %}
|
||||
<h1>Update <span class="text-info">{{ object }}</span></h1>
|
||||
{% endblocktrans %}
|
||||
{% else %}
|
||||
<h1>{% trans "Add a Head Circumference Entry" %}</h1>
|
||||
{% endif %}
|
||||
{% include 'babybuddy/form.html' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block javascript %}
|
||||
<script type="text/javascript">
|
||||
BabyBuddy.DatetimePicker.init($('#datetimepicker_date'), {
|
||||
format: 'L',
|
||||
extraFormats: ['YYYY-MM-DD']
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
|
@ -0,0 +1,73 @@
|
|||
{% extends 'babybuddy/page.html' %}
|
||||
{% load i18n widget_tweaks %}
|
||||
|
||||
{% block title %}{% trans "Head Circumference" %}{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<li class="breadcrumb-item active" aria-current="page">{% trans "Head Circumference" %}</li>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>
|
||||
{% trans "Head Circumference" %}
|
||||
{% if perms.core.add_head_circumference %}
|
||||
<a href="{% url 'core:head-circumference-add' %}" class="btn btn-sm btn-success">
|
||||
<i class="icon-head-circumference" aria-hidden="true"></i> {% trans "Add Head Circumference" %}
|
||||
</a>
|
||||
{% endif %}
|
||||
</h1>
|
||||
{% include 'babybuddy/filter.html' %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-instances">
|
||||
<thead class="thead-inverse">
|
||||
<tr>
|
||||
<th>{% trans "Actions" %}</th>
|
||||
<th>{% trans "Date" %}</th>
|
||||
{% if not unique_child %}
|
||||
<th>{% trans "Child" %}</th>
|
||||
{% endif %}
|
||||
<th>{% trans "Head Circumference" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for head_circumference in object_list %}
|
||||
{% cycle "odd" "even" as row_class silent %}
|
||||
<tr class="{{ row_class }}">
|
||||
<td>
|
||||
<div class="btn-group btn-group-sm" role="group" aria-label="{% trans "Actions" %}">
|
||||
|
||||
{% if perms.core.change_head_circumference %}
|
||||
<a href="{% url 'core:head-circumference-update' head_circumference.id %}" class="btn btn-primary">
|
||||
<i class="icon-update" aria-hidden="true"></i>
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
{% if perms.core.delete_head_circumference %}
|
||||
<a href="{% url 'core:head-circumference-delete' head_circumference.id %}" class="btn btn-danger">
|
||||
<i class="icon-delete" aria-hidden="true"></i>
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
</td>
|
||||
<th scope="row">{{ head_circumference.date }}</th>
|
||||
{% if not unique_child %}
|
||||
<td><a href="{% url 'core:child' head_circumference.child.slug %}">{{ head_circumference.child }}</a></td>
|
||||
{% endif %}
|
||||
<td>{{ head_circumference.head_circumference }}</td>
|
||||
</tr>
|
||||
{% if head_circumference.notes %}
|
||||
<tr class="{{ row_class }} row-details">
|
||||
<td colspan="4"><i class="icon-note mr-2" aria-hidden="true"></i>{{ head_circumference.notes }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% empty %}
|
||||
<tr>
|
||||
<th colspan="4">{% trans "No head circumference entries found." %}</th>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% include 'babybuddy/paginator.html' %}
|
||||
{% endblock %}
|
|
@ -0,0 +1,20 @@
|
|||
{% extends 'babybuddy/page.html' %}
|
||||
{% load i18n widget_tweaks %}
|
||||
|
||||
{% block title %}{% trans "Delete a Height Entry" %}{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<li class="breadcrumb-item"><a href="{% url 'core:height-list' %}">{% trans "Height" %}</a></li>
|
||||
<li class="breadcrumb-item active" aria-current="page">{% trans "Delete" %}</li>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<form role="form" method="post">
|
||||
{% csrf_token %}
|
||||
{% blocktrans trimmed %}
|
||||
<h1>Are you sure you want to delete <span class="text-info">{{ object }}</span>?</h1>
|
||||
{% endblocktrans %}
|
||||
<input type="submit" value="{% trans "Delete" %}" class="btn btn-danger" />
|
||||
<a href="{% url 'core:height-list' %}" class="btn btn-default">{% trans "Cancel" %}</a>
|
||||
</form>
|
||||
{% endblock %}
|
|
@ -0,0 +1,39 @@
|
|||
{% extends 'babybuddy/page.html' %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}
|
||||
{% if object %}
|
||||
{{ object }}
|
||||
{% else %}
|
||||
{% trans "Add a Height Entry" %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<li class="breadcrumb-item"><a href="{% url 'core:height-list' %}">{% trans "Height" %}</a></li>
|
||||
{% if object %}
|
||||
<li class="breadcrumb-item active" aria-current="page">{% trans "Update" %}</li>
|
||||
{% else %}
|
||||
<li class="breadcrumb-item active" aria-current="page">{% trans "Add a Height Entry" %}</li>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% if object %}
|
||||
{% blocktrans trimmed %}
|
||||
<h1>Update <span class="text-info">{{ object }}</span></h1>
|
||||
{% endblocktrans %}
|
||||
{% else %}
|
||||
<h1>{% trans "Add a Height Entry" %}</h1>
|
||||
{% endif %}
|
||||
{% include 'babybuddy/form.html' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block javascript %}
|
||||
<script type="text/javascript">
|
||||
BabyBuddy.DatetimePicker.init($('#datetimepicker_date'), {
|
||||
format: 'L',
|
||||
extraFormats: ['YYYY-MM-DD']
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
|
@ -0,0 +1,73 @@
|
|||
{% extends 'babybuddy/page.html' %}
|
||||
{% load i18n widget_tweaks %}
|
||||
|
||||
{% block title %}{% trans "Height" %}{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<li class="breadcrumb-item active" aria-current="page">{% trans "Height" %}</li>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>
|
||||
{% trans "Height" %}
|
||||
{% if perms.core.add_height %}
|
||||
<a href="{% url 'core:height-add' %}" class="btn btn-sm btn-success">
|
||||
<i class="icon-height" aria-hidden="true"></i> {% trans "Add Height" %}
|
||||
</a>
|
||||
{% endif %}
|
||||
</h1>
|
||||
{% include 'babybuddy/filter.html' %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-instances">
|
||||
<thead class="thead-inverse">
|
||||
<tr>
|
||||
<th>{% trans "Actions" %}</th>
|
||||
<th>{% trans "Date" %}</th>
|
||||
{% if not unique_child %}
|
||||
<th>{% trans "Child" %}</th>
|
||||
{% endif %}
|
||||
<th>{% trans "Height" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for height in object_list %}
|
||||
{% cycle "odd" "even" as row_class silent %}
|
||||
<tr class="{{ row_class }}">
|
||||
<td>
|
||||
<div class="btn-group btn-group-sm" role="group" aria-label="{% trans "Actions" %}">
|
||||
|
||||
{% if perms.core.change_height %}
|
||||
<a href="{% url 'core:height-update' height.id %}" class="btn btn-primary">
|
||||
<i class="icon-update" aria-hidden="true"></i>
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
{% if perms.core.delete_height %}
|
||||
<a href="{% url 'core:height-delete' height.id %}" class="btn btn-danger">
|
||||
<i class="icon-delete" aria-hidden="true"></i>
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
</td>
|
||||
<th scope="row">{{ height.date }}</th>
|
||||
{% if not unique_child %}
|
||||
<td><a href="{% url 'core:child' height.child.slug %}">{{ height.child }}</a></td>
|
||||
{% endif %}
|
||||
<td>{{ height.height }}</td>
|
||||
</tr>
|
||||
{% if height.notes %}
|
||||
<tr class="{{ row_class }} row-details">
|
||||
<td colspan="4"><i class="icon-note mr-2" aria-hidden="true"></i>{{ height.notes }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% empty %}
|
||||
<tr>
|
||||
<th colspan="4">{% trans "No height entries found." %}</th>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% include 'babybuddy/paginator.html' %}
|
||||
{% endblock %}
|
39
core/urls.py
39
core/urls.py
|
@ -158,4 +158,43 @@ urlpatterns = [
|
|||
views.WeightDelete.as_view(),
|
||||
name='weight-delete'
|
||||
),
|
||||
|
||||
path('height/', views.HeightList.as_view(), name='height-list'),
|
||||
path('height/add/', views.HeightAdd.as_view(), name='height-add'),
|
||||
path(
|
||||
'height/<int:pk>/',
|
||||
views.HeightUpdate.as_view(),
|
||||
name='height-update'
|
||||
),
|
||||
path(
|
||||
'height/<int:pk>/delete/',
|
||||
views.HeightDelete.as_view(),
|
||||
name='height-delete'
|
||||
),
|
||||
|
||||
path('head-circumference/', views.HeadCircumferenceList.as_view(), name='head-circumference-list'),
|
||||
path('head-circumference/add/', views.HeadCircumferenceAdd.as_view(), name='head-circumference-add'),
|
||||
path(
|
||||
'head-circumference/<int:pk>/',
|
||||
views.HeadCircumferenceUpdate.as_view(),
|
||||
name='head-circumference-update'
|
||||
),
|
||||
path(
|
||||
'head-circumference/<int:pk>/delete/',
|
||||
views.HeadCircumferenceDelete.as_view(),
|
||||
name='head-circumference-delete'
|
||||
),
|
||||
|
||||
path('bmi/', views.BMIList.as_view(), name='bmi-list'),
|
||||
path('bmi/add/', views.BMIAdd.as_view(), name='bmi-add'),
|
||||
path(
|
||||
'bmi/<int:pk>/',
|
||||
views.BMIUpdate.as_view(),
|
||||
name='bmi-update'
|
||||
),
|
||||
path(
|
||||
'bmi/<int:pk>/delete/',
|
||||
views.BMIDelete.as_view(),
|
||||
name='bmi-delete'
|
||||
),
|
||||
]
|
||||
|
|
|
@ -469,3 +469,87 @@ class WeightDelete(CoreDeleteView):
|
|||
model = models.Weight
|
||||
permission_required = ('core.delete_weight',)
|
||||
success_url = reverse_lazy('core:weight-list')
|
||||
|
||||
class HeightList(PermissionRequiredMixin, BabyBuddyFilterView):
|
||||
model = models.Height
|
||||
template_name = 'core/height_list.html'
|
||||
permission_required = ('core.view_height',)
|
||||
paginate_by = 10
|
||||
filterset_fields = ('child',)
|
||||
|
||||
|
||||
class HeightAdd(CoreAddView):
|
||||
model = models.Height
|
||||
permission_required = ('core.add_height',)
|
||||
form_class = forms.HeightForm
|
||||
success_url = reverse_lazy('core:height-list')
|
||||
|
||||
|
||||
class HeightUpdate(CoreUpdateView):
|
||||
model = models.Height
|
||||
permission_required = ('core.change_height',)
|
||||
form_class = forms.HeightForm
|
||||
success_url = reverse_lazy('core:height-list')
|
||||
|
||||
|
||||
class HeightDelete(CoreDeleteView):
|
||||
model = models.Height
|
||||
permission_required = ('core.delete_height',)
|
||||
success_url = reverse_lazy('core:height-list')
|
||||
|
||||
class HeadCircumferenceList(PermissionRequiredMixin, BabyBuddyFilterView):
|
||||
model = models.HeadCircumference
|
||||
template_name = 'core/head_circumference_list.html'
|
||||
permission_required = ('core.view_head_circumference',)
|
||||
paginate_by = 10
|
||||
filterset_fields = ('child',)
|
||||
|
||||
|
||||
class HeadCircumferenceAdd(CoreAddView):
|
||||
model = models.HeadCircumference
|
||||
template_name = 'core/head_circumference_form.html'
|
||||
permission_required = ('core.add_head_circumference',)
|
||||
form_class = forms.HeadCircumferenceForm
|
||||
success_url = reverse_lazy('core:head-circumference-list')
|
||||
|
||||
|
||||
class HeadCircumferenceUpdate(CoreUpdateView):
|
||||
model = models.HeadCircumference
|
||||
template_name = 'core/head_circumference_form.html'
|
||||
permission_required = ('core.change_head_circumference',)
|
||||
form_class = forms.HeadCircumferenceForm
|
||||
success_url = reverse_lazy('core:head-circumference-list')
|
||||
|
||||
|
||||
class HeadCircumferenceDelete(CoreDeleteView):
|
||||
model = models.HeadCircumference
|
||||
template_name = 'core/head_circumference_delete.html'
|
||||
permission_required = ('core.delete_head_circumference',)
|
||||
success_url = reverse_lazy('core:head-circumference-list')
|
||||
|
||||
class BMIList(PermissionRequiredMixin, BabyBuddyFilterView):
|
||||
model = models.BMI
|
||||
template_name = 'core/bmi_list.html'
|
||||
permission_required = ('core.view_bmi',)
|
||||
paginate_by = 10
|
||||
filterset_fields = ('child',)
|
||||
|
||||
|
||||
class BMIAdd(CoreAddView):
|
||||
model = models.BMI
|
||||
permission_required = ('core.add_bmi',)
|
||||
form_class = forms.BMIForm
|
||||
success_url = reverse_lazy('core:bmi-list')
|
||||
|
||||
|
||||
class BMIUpdate(CoreUpdateView):
|
||||
model = models.BMI
|
||||
permission_required = ('core.change_bmi',)
|
||||
form_class = forms.BMIForm
|
||||
success_url = reverse_lazy('core:bmi-list')
|
||||
|
||||
|
||||
class BMIDelete(CoreDeleteView):
|
||||
model = models.BMI
|
||||
permission_required = ('core.delete_bmi',)
|
||||
success_url = reverse_lazy('core:bmi-list')
|
|
@ -29,6 +29,9 @@
|
|||
<a class="dropdown-item" href="{% url 'reports:report-sleep-totals-child' object.slug %}">{% trans "Sleep Totals" %}</a>
|
||||
<a class="dropdown-item" href="{% url 'reports:report-tummytime-duration-child' object.slug %}">{% trans "Tummy Time Durations (Sum)" %}</a>
|
||||
<a class="dropdown-item" href="{% url 'reports:report-weight-weight-child' object.slug %}">{% trans "Weight" %}</a>
|
||||
<a class="dropdown-item" href="{% url 'reports:report-height-height-child' object.slug %}">{% trans "Height" %}</a>
|
||||
<a class="dropdown-item" href="{% url 'reports:report-head-circumference-head-circumference-child' object.slug %}">{% trans "Head Circumference" %}</a>
|
||||
<a class="dropdown-item" href="{% url 'reports:report-bmi-bmi-child' object.slug %}">{% trans "BMI" %}</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -313,6 +313,27 @@ def card_statistics(context, child):
|
|||
'stat': weight['change_weekly'],
|
||||
'title': _('Weight change per week')})
|
||||
|
||||
height = _height_statistics(child)
|
||||
if height:
|
||||
stats.append({
|
||||
'type': 'float',
|
||||
'stat': height['change_weekly'],
|
||||
'title': _('Height change per week')})
|
||||
|
||||
head_circumference = _head_circumference_statistics(child)
|
||||
if head_circumference:
|
||||
stats.append({
|
||||
'type': 'float',
|
||||
'stat': head_circumference['change_weekly'],
|
||||
'title': _('Head circumference change per week')})
|
||||
|
||||
bmi = _bmi_statistics(child)
|
||||
if bmi:
|
||||
stats.append({
|
||||
'type': 'float',
|
||||
'stat': bmi['change_weekly'],
|
||||
'title': _('BMI change per week')})
|
||||
|
||||
empty = len(stats) == 0
|
||||
|
||||
return {
|
||||
|
@ -476,6 +497,71 @@ def _weight_statistics(child):
|
|||
|
||||
return weight
|
||||
|
||||
def _height_statistics(child):
|
||||
"""
|
||||
Statistical height data.
|
||||
:param child: an instance of the Child model.
|
||||
:returns: a dictionary of statistics.
|
||||
"""
|
||||
height = {'change_weekly': 0.0}
|
||||
|
||||
instances = models.Height.objects.filter(child=child).order_by('-date')
|
||||
if len(instances) == 0:
|
||||
return False
|
||||
|
||||
newest = instances.first()
|
||||
oldest = instances.last()
|
||||
|
||||
if newest != oldest:
|
||||
height_change = newest.height - oldest.height
|
||||
weeks = (newest.date - oldest.date).days/7
|
||||
height['change_weekly'] = height_change/weeks
|
||||
|
||||
return height
|
||||
|
||||
def _head_circumference_statistics(child):
|
||||
"""
|
||||
Statistical head circumference data.
|
||||
:param child: an instance of the Child model.
|
||||
:returns: a dictionary of statistics.
|
||||
"""
|
||||
head_circumference = {'change_weekly': 0.0}
|
||||
|
||||
instances = models.HeadCircumference.objects.filter(child=child).order_by('-date')
|
||||
if len(instances) == 0:
|
||||
return False
|
||||
|
||||
newest = instances.first()
|
||||
oldest = instances.last()
|
||||
|
||||
if newest != oldest:
|
||||
head_circumference_change = newest.head_circumference - oldest.head_circumference
|
||||
weeks = (newest.date - oldest.date).days/7
|
||||
head_circumference['change_weekly'] = head_circumference_change/weeks
|
||||
|
||||
return head_circumference
|
||||
|
||||
def _bmi_statistics(child):
|
||||
"""
|
||||
Statistical BMI data.
|
||||
:param child: an instance of the Child model.
|
||||
:returns: a dictionary of statistics.
|
||||
"""
|
||||
bmi = {'change_weekly': 0.0}
|
||||
|
||||
instances = models.BMI.objects.filter(child=child).order_by('-date')
|
||||
if len(instances) == 0:
|
||||
return False
|
||||
|
||||
newest = instances.first()
|
||||
oldest = instances.last()
|
||||
|
||||
if newest != oldest:
|
||||
bmi_change = newest.bmi - oldest.bmi
|
||||
weeks = (newest.date - oldest.date).days/7
|
||||
bmi['change_weekly'] = bmi_change/weeks
|
||||
|
||||
return bmi
|
||||
|
||||
@register.inclusion_tag('cards/timer_list.html', takes_context=True)
|
||||
def card_timer_list(context, child=None):
|
||||
|
|
|
@ -210,6 +210,21 @@ class TemplateTagsTestCase(TestCase):
|
|||
'title': 'Weight change per week',
|
||||
'stat': 1.0, 'type':
|
||||
'float'
|
||||
},
|
||||
{
|
||||
'title': 'Height change per week',
|
||||
'stat': 1.0, 'type':
|
||||
'float'
|
||||
},
|
||||
{
|
||||
'title': 'Head circumference change per week',
|
||||
'stat': 1.0, 'type':
|
||||
'float'
|
||||
},
|
||||
{
|
||||
'title': 'BMI change per week',
|
||||
'stat': 1.0, 'type':
|
||||
'float'
|
||||
}
|
||||
]
|
||||
|
||||
|
|
Binary file not shown.
|
@ -2,7 +2,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: Baby Buddy\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-12-18 18:43+0000\n"
|
||||
"POT-Creation-Date: 2021-12-28 23:25-0800\n"
|
||||
"Language: en-GB\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
|
@ -10,7 +10,7 @@ msgstr ""
|
|||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: babybuddy/admin.py:12 babybuddy/admin.py:13
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:270
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:326
|
||||
#: babybuddy/templates/babybuddy/user_settings_form.html:8
|
||||
msgid "Settings"
|
||||
msgstr ""
|
||||
|
@ -180,11 +180,11 @@ msgstr ""
|
|||
|
||||
#: babybuddy/templates/admin/base_site.html:4
|
||||
#: babybuddy/templates/admin/base_site.html:7
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:277
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:338
|
||||
msgid "Database Admin"
|
||||
msgstr ""
|
||||
|
||||
#: babybuddy/templates/babybuddy/base.html:23
|
||||
#: babybuddy/templates/babybuddy/base.html:36
|
||||
msgid "Home"
|
||||
msgstr ""
|
||||
|
||||
|
@ -227,7 +227,7 @@ msgid "Diaper Change"
|
|||
msgstr "Nappy Change"
|
||||
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:57
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:218 core/models.py:243
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:274 core/models.py:243
|
||||
#: core/models.py:247 core/templates/core/timer_detail.html:43
|
||||
msgid "Feeding"
|
||||
msgstr ""
|
||||
|
@ -239,7 +239,7 @@ msgid "Note"
|
|||
msgstr ""
|
||||
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:69
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:225
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:281
|
||||
#: babybuddy/templates/babybuddy/welcome.html:42 core/models.py:330
|
||||
#: core/models.py:331 core/models.py:334
|
||||
#: core/templates/core/sleep_confirm_delete.html:7
|
||||
|
@ -250,7 +250,7 @@ msgid "Sleep"
|
|||
msgstr ""
|
||||
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:75
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:158 core/models.py:369
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:172 core/models.py:369
|
||||
#: core/models.py:383 core/models.py:384 core/models.py:387
|
||||
#: core/templates/core/temperature_confirm_delete.html:7
|
||||
#: core/templates/core/temperature_form.html:13
|
||||
|
@ -262,7 +262,7 @@ msgid "Temperature"
|
|||
msgstr ""
|
||||
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:81
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:238
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:294
|
||||
#: babybuddy/templates/babybuddy/welcome.html:50 core/models.py:537
|
||||
#: core/models.py:538 core/models.py:541
|
||||
#: core/templates/core/timer_detail.html:59
|
||||
|
@ -275,7 +275,7 @@ msgid "Tummy Time"
|
|||
msgstr ""
|
||||
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:87
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:172 core/models.py:567
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:186 core/models.py:567
|
||||
#: core/models.py:581 core/models.py:582 core/models.py:585
|
||||
#: core/templates/core/weight_confirm_delete.html:7
|
||||
#: core/templates/core/weight_form.html:13
|
||||
|
@ -311,8 +311,12 @@ msgstr ""
|
|||
#: babybuddy/templates/babybuddy/nav-dropdown.html:136 core/models.py:104
|
||||
#: core/models.py:137 core/models.py:196 core/models.py:267 core/models.py:300
|
||||
#: core/models.py:364 core/models.py:401 core/models.py:509 core/models.py:562
|
||||
#: core/models.py:596 core/models.py:630 core/models.py:664
|
||||
#: core/templates/core/bmi_list.html:27
|
||||
#: core/templates/core/diaperchange_list.html:27
|
||||
#: core/templates/core/feeding_list.html:27
|
||||
#: core/templates/core/head_circumference_list.html:27
|
||||
#: core/templates/core/height_list.html:27
|
||||
#: core/templates/core/note_list.html:27 core/templates/core/sleep_list.html:28
|
||||
#: core/templates/core/temperature_list.html:27
|
||||
#: core/templates/core/timer_list.html:27
|
||||
|
@ -323,34 +327,95 @@ msgstr ""
|
|||
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:144 core/models.py:158
|
||||
#: core/models.py:236 core/models.py:282 core/models.py:322 core/models.py:376
|
||||
#: core/models.py:574 core/templates/core/note_confirm_delete.html:7
|
||||
#: core/models.py:574 core/models.py:608 core/models.py:642 core/models.py:676
|
||||
#: core/templates/core/note_confirm_delete.html:7
|
||||
#: core/templates/core/note_form.html:13 core/templates/core/note_list.html:4
|
||||
#: core/templates/core/note_list.html:7 core/templates/core/note_list.html:12
|
||||
msgid "Notes"
|
||||
msgstr ""
|
||||
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:164
|
||||
msgid "Temperature reading"
|
||||
msgid "Measurements"
|
||||
msgstr ""
|
||||
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:178
|
||||
msgid "Weight entry"
|
||||
msgid "Temperature reading"
|
||||
msgstr ""
|
||||
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:192
|
||||
msgid "Weight entry"
|
||||
msgstr ""
|
||||
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:200 core/models.py:601
|
||||
#: core/models.py:615 core/models.py:616 core/models.py:619
|
||||
#: core/templates/core/height_confirm_delete.html:7
|
||||
#: core/templates/core/height_form.html:13
|
||||
#: core/templates/core/height_list.html:4
|
||||
#: core/templates/core/height_list.html:7
|
||||
#: core/templates/core/height_list.html:12
|
||||
#: core/templates/core/height_list.html:29
|
||||
#: dashboard/templates/dashboard/child_button_group.html:32
|
||||
#: reports/graphs/height_height.py:19 reports/graphs/height_height.py:30
|
||||
#: reports/templates/reports/height_change.html:4
|
||||
#: reports/templates/reports/height_change.html:8
|
||||
msgid "Height"
|
||||
msgstr ""
|
||||
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:206
|
||||
msgid "Height entry"
|
||||
msgstr ""
|
||||
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:214 core/models.py:635
|
||||
#: core/models.py:649 core/models.py:650 core/models.py:653
|
||||
#: core/templates/core/head_circumference_confirm_delete.html:7
|
||||
#: core/templates/core/head_circumference_form.html:13
|
||||
#: core/templates/core/head_circumference_list.html:4
|
||||
#: core/templates/core/head_circumference_list.html:7
|
||||
#: core/templates/core/head_circumference_list.html:12
|
||||
#: core/templates/core/head_circumference_list.html:29
|
||||
#: dashboard/templates/dashboard/child_button_group.html:33
|
||||
#: reports/graphs/head_circumference_head_circumference.py:19
|
||||
#: reports/graphs/head_circumference_head_circumference.py:30
|
||||
#: reports/templates/reports/head_circumference_change.html:4
|
||||
#: reports/templates/reports/head_circumference_change.html:8
|
||||
msgid "Head Circumference"
|
||||
msgstr ""
|
||||
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:220
|
||||
msgid "Head Circumference entry"
|
||||
msgstr ""
|
||||
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:228 core/models.py:669
|
||||
#: core/models.py:683 core/models.py:684 core/models.py:687
|
||||
#: core/templates/core/bmi_confirm_delete.html:7
|
||||
#: core/templates/core/bmi_form.html:13 core/templates/core/bmi_list.html:4
|
||||
#: core/templates/core/bmi_list.html:7 core/templates/core/bmi_list.html:12
|
||||
#: core/templates/core/bmi_list.html:29
|
||||
#: dashboard/templates/dashboard/child_button_group.html:34
|
||||
#: reports/graphs/bmi_bmi.py:19 reports/graphs/bmi_bmi.py:30
|
||||
#: reports/templates/reports/bmi_change.html:4
|
||||
#: reports/templates/reports/bmi_change.html:8
|
||||
msgid "BMI"
|
||||
msgstr ""
|
||||
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:234
|
||||
msgid "BMI entry"
|
||||
msgstr ""
|
||||
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:248
|
||||
msgid "Activities"
|
||||
msgstr ""
|
||||
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:199
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:255
|
||||
#: reports/graphs/diaperchange_lifetimes.py:27
|
||||
msgid "Changes"
|
||||
msgstr ""
|
||||
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:205
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:261
|
||||
msgid "Change"
|
||||
msgstr ""
|
||||
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:212
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:268
|
||||
#: babybuddy/templates/babybuddy/welcome.html:34 core/models.py:244
|
||||
#: core/templates/core/feeding_confirm_delete.html:7
|
||||
#: core/templates/core/feeding_form.html:13
|
||||
|
@ -360,15 +425,15 @@ msgstr ""
|
|||
msgid "Feedings"
|
||||
msgstr ""
|
||||
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:231
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:287
|
||||
msgid "Sleep entry"
|
||||
msgstr ""
|
||||
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:244
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:300
|
||||
msgid "Tummy Time entry"
|
||||
msgstr ""
|
||||
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:269
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:325
|
||||
#: babybuddy/templates/babybuddy/user_list.html:17
|
||||
#: babybuddy/templates/babybuddy/user_password_form.html:7
|
||||
#: babybuddy/templates/babybuddy/user_settings_form.html:7 core/models.py:434
|
||||
|
@ -376,23 +441,23 @@ msgstr ""
|
|||
msgid "User"
|
||||
msgstr ""
|
||||
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:271
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:327
|
||||
msgid "Password"
|
||||
msgstr ""
|
||||
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:272
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:331
|
||||
msgid "Logout"
|
||||
msgstr ""
|
||||
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:273
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:334
|
||||
msgid "Site"
|
||||
msgstr ""
|
||||
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:274
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:335
|
||||
msgid "API Browser"
|
||||
msgstr ""
|
||||
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:276
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:337
|
||||
#: babybuddy/templates/babybuddy/user_confirm_delete.html:7
|
||||
#: babybuddy/templates/babybuddy/user_form.html:13
|
||||
#: babybuddy/templates/babybuddy/user_list.html:4
|
||||
|
@ -400,15 +465,15 @@ msgstr ""
|
|||
msgid "Users"
|
||||
msgstr ""
|
||||
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:279
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:340
|
||||
msgid "Support"
|
||||
msgstr ""
|
||||
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:281
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:342
|
||||
msgid "Source Code"
|
||||
msgstr ""
|
||||
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:283
|
||||
#: babybuddy/templates/babybuddy/nav-dropdown.html:344
|
||||
msgid "Chat / Support"
|
||||
msgstr ""
|
||||
|
||||
|
@ -437,12 +502,18 @@ msgid "Delete User"
|
|||
msgstr ""
|
||||
|
||||
#: babybuddy/templates/babybuddy/user_confirm_delete.html:9
|
||||
#: core/templates/core/bmi_confirm_delete.html:8
|
||||
#: core/templates/core/bmi_confirm_delete.html:17
|
||||
#: core/templates/core/child_confirm_delete.html:9
|
||||
#: core/templates/core/child_confirm_delete.html:31
|
||||
#: core/templates/core/diaperchange_confirm_delete.html:8
|
||||
#: core/templates/core/diaperchange_confirm_delete.html:17
|
||||
#: core/templates/core/feeding_confirm_delete.html:8
|
||||
#: core/templates/core/feeding_confirm_delete.html:17
|
||||
#: core/templates/core/head_circumference_confirm_delete.html:8
|
||||
#: core/templates/core/head_circumference_confirm_delete.html:17
|
||||
#: core/templates/core/height_confirm_delete.html:8
|
||||
#: core/templates/core/height_confirm_delete.html:17
|
||||
#: core/templates/core/note_confirm_delete.html:8
|
||||
#: core/templates/core/note_confirm_delete.html:17
|
||||
#: core/templates/core/sleep_confirm_delete.html:8
|
||||
|
@ -456,14 +527,17 @@ msgstr ""
|
|||
#: core/templates/core/tummytime_confirm_delete.html:17
|
||||
#: core/templates/core/weight_confirm_delete.html:8
|
||||
#: core/templates/core/weight_confirm_delete.html:17
|
||||
#: dashboard/templates/dashboard/child_button_group.html:45
|
||||
#: dashboard/templates/dashboard/child_button_group.html:48
|
||||
msgid "Delete"
|
||||
msgstr ""
|
||||
|
||||
#: babybuddy/templates/babybuddy/user_confirm_delete.html:15
|
||||
#: core/templates/core/bmi_confirm_delete.html:14
|
||||
#: core/templates/core/child_confirm_delete.html:15
|
||||
#: core/templates/core/diaperchange_confirm_delete.html:14
|
||||
#: core/templates/core/feeding_confirm_delete.html:14
|
||||
#: core/templates/core/head_circumference_confirm_delete.html:14
|
||||
#: core/templates/core/height_confirm_delete.html:14
|
||||
#: core/templates/core/note_confirm_delete.html:14
|
||||
#: core/templates/core/sleep_confirm_delete.html:14
|
||||
#: core/templates/core/temperature_confirm_delete.html:14
|
||||
|
@ -477,9 +551,12 @@ msgid ""
|
|||
msgstr ""
|
||||
|
||||
#: babybuddy/templates/babybuddy/user_confirm_delete.html:19
|
||||
#: core/templates/core/bmi_confirm_delete.html:18
|
||||
#: core/templates/core/child_confirm_delete.html:32
|
||||
#: core/templates/core/diaperchange_confirm_delete.html:18
|
||||
#: core/templates/core/feeding_confirm_delete.html:18
|
||||
#: core/templates/core/head_circumference_confirm_delete.html:18
|
||||
#: core/templates/core/height_confirm_delete.html:18
|
||||
#: core/templates/core/note_confirm_delete.html:18
|
||||
#: core/templates/core/sleep_confirm_delete.html:18
|
||||
#: core/templates/core/temperature_confirm_delete.html:18
|
||||
|
@ -498,9 +575,11 @@ msgid "Create User"
|
|||
msgstr ""
|
||||
|
||||
#: babybuddy/templates/babybuddy/user_form.html:16
|
||||
#: core/templates/core/child_form.html:16
|
||||
#: core/templates/core/bmi_form.html:15 core/templates/core/child_form.html:16
|
||||
#: core/templates/core/diaperchange_form.html:15
|
||||
#: core/templates/core/feeding_form.html:15
|
||||
#: core/templates/core/head_circumference_form.html:15
|
||||
#: core/templates/core/height_form.html:15
|
||||
#: core/templates/core/note_form.html:15 core/templates/core/sleep_form.html:15
|
||||
#: core/templates/core/temperature_form.html:15
|
||||
#: core/templates/core/timer_form.html:10
|
||||
|
@ -510,9 +589,11 @@ msgid "Update"
|
|||
msgstr ""
|
||||
|
||||
#: babybuddy/templates/babybuddy/user_form.html:24
|
||||
#: core/templates/core/child_form.html:24
|
||||
#: core/templates/core/bmi_form.html:23 core/templates/core/child_form.html:24
|
||||
#: core/templates/core/diaperchange_form.html:23
|
||||
#: core/templates/core/feeding_form.html:23
|
||||
#: core/templates/core/head_circumference_form.html:23
|
||||
#: core/templates/core/height_form.html:23
|
||||
#: core/templates/core/note_form.html:23 core/templates/core/sleep_form.html:23
|
||||
#: core/templates/core/temperature_form.html:23
|
||||
#: core/templates/core/timer_form.html:18
|
||||
|
@ -546,12 +627,17 @@ msgid "Active"
|
|||
msgstr ""
|
||||
|
||||
#: babybuddy/templates/babybuddy/user_list.html:23
|
||||
#: core/templates/core/bmi_list.html:24 core/templates/core/bmi_list.html:37
|
||||
#: core/templates/core/child_list.html:28
|
||||
#: core/templates/core/child_list.html:48
|
||||
#: core/templates/core/diaperchange_list.html:24
|
||||
#: core/templates/core/diaperchange_list.html:39
|
||||
#: core/templates/core/feeding_list.html:24
|
||||
#: core/templates/core/feeding_list.html:42
|
||||
#: core/templates/core/head_circumference_list.html:24
|
||||
#: core/templates/core/head_circumference_list.html:37
|
||||
#: core/templates/core/height_list.html:24
|
||||
#: core/templates/core/height_list.html:37
|
||||
#: core/templates/core/note_list.html:24 core/templates/core/note_list.html:36
|
||||
#: core/templates/core/sleep_list.html:24
|
||||
#: core/templates/core/sleep_list.html:39
|
||||
|
@ -704,30 +790,30 @@ msgid ""
|
|||
"you will receive instructions for resetting your password."
|
||||
msgstr ""
|
||||
|
||||
#: babybuddy/views.py:66
|
||||
#: babybuddy/views.py:78
|
||||
#, python-format
|
||||
msgid "User %(username)s added!"
|
||||
msgstr ""
|
||||
|
||||
#: babybuddy/views.py:76
|
||||
#: babybuddy/views.py:88
|
||||
#, python-format
|
||||
msgid "User %(username)s updated."
|
||||
msgstr ""
|
||||
|
||||
#: babybuddy/views.py:88
|
||||
#: babybuddy/views.py:100
|
||||
#, python-brace-format
|
||||
msgid "User {user} deleted."
|
||||
msgstr ""
|
||||
|
||||
#: babybuddy/views.py:111
|
||||
#: babybuddy/views.py:123
|
||||
msgid "Password updated."
|
||||
msgstr ""
|
||||
|
||||
#: babybuddy/views.py:134
|
||||
#: babybuddy/views.py:146
|
||||
msgid "User API key regenerated."
|
||||
msgstr ""
|
||||
|
||||
#: babybuddy/views.py:149
|
||||
#: babybuddy/views.py:161
|
||||
msgid "Settings saved!"
|
||||
msgstr ""
|
||||
|
||||
|
@ -915,16 +1001,41 @@ msgstr ""
|
|||
msgid "Milestone"
|
||||
msgstr ""
|
||||
|
||||
#: core/models.py:572 core/templates/core/feeding_list.html:25
|
||||
#: core/templates/core/weight_list.html:25
|
||||
#: core/models.py:572 core/models.py:606 core/models.py:640 core/models.py:674
|
||||
#: core/templates/core/bmi_list.html:25
|
||||
#: core/templates/core/feeding_list.html:25
|
||||
#: core/templates/core/head_circumference_list.html:25
|
||||
#: core/templates/core/height_list.html:25
|
||||
#: core/templates/core/weight_list.html:25 reports/graphs/bmi_bmi.py:28
|
||||
#: reports/graphs/diaperchange_amounts.py:37
|
||||
#: reports/graphs/diaperchange_types.py:47 reports/graphs/feeding_amounts.py:37
|
||||
#: reports/graphs/feeding_duration.py:54 reports/graphs/sleep_pattern.py:146
|
||||
#: reports/graphs/feeding_duration.py:54
|
||||
#: reports/graphs/head_circumference_head_circumference.py:28
|
||||
#: reports/graphs/height_height.py:28 reports/graphs/sleep_pattern.py:146
|
||||
#: reports/graphs/sleep_totals.py:51 reports/graphs/tummytime_duration.py:49
|
||||
#: reports/graphs/weight_weight.py:28
|
||||
msgid "Date"
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/core/bmi_confirm_delete.html:4
|
||||
msgid "Delete a BMI Entry"
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/core/bmi_form.html:8 core/templates/core/bmi_form.html:17
|
||||
#: core/templates/core/bmi_form.html:27
|
||||
msgid "Add a BMI Entry"
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/core/bmi_list.html:15
|
||||
msgid "Add BMI"
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/core/bmi_list.html:66
|
||||
#, fuzzy
|
||||
#| msgid "No diaper changes found."
|
||||
msgid "No bmi entries found."
|
||||
msgstr "No nappy changes found."
|
||||
|
||||
#: core/templates/core/child_confirm_delete.html:4
|
||||
msgid "Delete a Child"
|
||||
msgstr ""
|
||||
|
@ -1012,6 +1123,46 @@ msgstr ""
|
|||
msgid "No feedings found."
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/core/head_circumference_confirm_delete.html:4
|
||||
msgid "Delete a Head Circumference Entry"
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/core/head_circumference_form.html:8
|
||||
#: core/templates/core/head_circumference_form.html:17
|
||||
#: core/templates/core/head_circumference_form.html:27
|
||||
msgid "Add a Head Circumference Entry"
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/core/head_circumference_list.html:15
|
||||
msgid "Add Head Circumference"
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/core/head_circumference_list.html:66
|
||||
#, fuzzy
|
||||
#| msgid "No diaper changes found."
|
||||
msgid "No head circumference entries found."
|
||||
msgstr "No nappy changes found."
|
||||
|
||||
#: core/templates/core/height_confirm_delete.html:4
|
||||
msgid "Delete a Height Entry"
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/core/height_form.html:8
|
||||
#: core/templates/core/height_form.html:17
|
||||
#: core/templates/core/height_form.html:27
|
||||
msgid "Add a Height Entry"
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/core/height_list.html:15
|
||||
msgid "Add Height"
|
||||
msgstr ""
|
||||
|
||||
#: core/templates/core/height_list.html:66
|
||||
#, fuzzy
|
||||
#| msgid "No diaper changes found."
|
||||
msgid "No height entries found."
|
||||
msgstr "No nappy changes found."
|
||||
|
||||
#: core/templates/core/note_confirm_delete.html:4
|
||||
msgid "Delete a Note"
|
||||
msgstr ""
|
||||
|
@ -1223,7 +1374,7 @@ msgid "%(since)s since previous"
|
|||
msgstr ""
|
||||
|
||||
#: core/templates/timeline/_timeline.html:56
|
||||
#: dashboard/templates/dashboard/child_button_group.html:38
|
||||
#: dashboard/templates/dashboard/child_button_group.html:41
|
||||
msgid "Edit"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1557,18 +1708,34 @@ msgstr ""
|
|||
msgid "Weight change per week"
|
||||
msgstr ""
|
||||
|
||||
#: dashboard/templatetags/cards.py:361
|
||||
#: dashboard/templatetags/cards.py:321
|
||||
msgid "Height change per week"
|
||||
msgstr ""
|
||||
|
||||
#: dashboard/templatetags/cards.py:328
|
||||
msgid "Head circumference change per week"
|
||||
msgstr ""
|
||||
|
||||
#: dashboard/templatetags/cards.py:335
|
||||
msgid "BMI change per week"
|
||||
msgstr ""
|
||||
|
||||
#: dashboard/templatetags/cards.py:382
|
||||
msgid "Feeding frequency (past 3 days)"
|
||||
msgstr ""
|
||||
|
||||
#: dashboard/templatetags/cards.py:365
|
||||
#: dashboard/templatetags/cards.py:386
|
||||
msgid "Feeding frequency (past 2 weeks)"
|
||||
msgstr ""
|
||||
|
||||
#: dashboard/templatetags/cards.py:371
|
||||
#: dashboard/templatetags/cards.py:392
|
||||
msgid "Feeding frequency"
|
||||
msgstr ""
|
||||
|
||||
#: reports/graphs/bmi_bmi.py:27
|
||||
msgid "<b>BMI</b>"
|
||||
msgstr ""
|
||||
|
||||
#: reports/graphs/diaperchange_amounts.py:27
|
||||
msgid "Diaper change amount"
|
||||
msgstr "Nappy change amount"
|
||||
|
@ -1633,6 +1800,14 @@ msgstr ""
|
|||
msgid "Number of feedings"
|
||||
msgstr ""
|
||||
|
||||
#: reports/graphs/head_circumference_head_circumference.py:27
|
||||
msgid "<b>Head Circumference</b>"
|
||||
msgstr ""
|
||||
|
||||
#: reports/graphs/height_height.py:27
|
||||
msgid "<b>Height</b>"
|
||||
msgstr ""
|
||||
|
||||
#: reports/graphs/sleep_pattern.py:143
|
||||
msgid "<b>Sleep Pattern</b>"
|
||||
msgstr ""
|
||||
|
|
1345
openapi-schema.yml
1345
openapi-schema.yml
File diff suppressed because it is too large
Load Diff
|
@ -7,3 +7,6 @@ from .sleep_pattern import sleep_pattern # NOQA
|
|||
from .sleep_totals import sleep_totals # NOQA
|
||||
from .tummytime_duration import tummytime_duration # NOQA
|
||||
from .weight_weight import weight_weight # NOQA
|
||||
from .height_height import height_height #NOQA
|
||||
from .head_circumference_head_circumference import head_circumference_head_circumference #NOQA
|
||||
from .bmi_bmi import bmi_bmi #NOQA
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
import plotly.offline as plotly
|
||||
import plotly.graph_objs as go
|
||||
|
||||
from reports import utils
|
||||
|
||||
|
||||
def bmi_bmi(objects):
|
||||
"""
|
||||
Create a graph showing bmi over time.
|
||||
:param objects: a QuerySet of BMI instances.
|
||||
:returns: a tuple of the the graph's html and javascript.
|
||||
"""
|
||||
objects = objects.order_by('-date')
|
||||
|
||||
trace = go.Scatter(
|
||||
name=_('BMI'),
|
||||
x=list(objects.values_list('date', flat=True)),
|
||||
y=list(objects.values_list('bmi', flat=True)),
|
||||
fill='tozeroy',
|
||||
)
|
||||
|
||||
layout_args = utils.default_graph_layout_options()
|
||||
layout_args['barmode'] = 'stack'
|
||||
layout_args['title'] = _('<b>BMI</b>')
|
||||
layout_args['xaxis']['title'] = _('Date')
|
||||
layout_args['xaxis']['rangeselector'] = utils.rangeselector_date()
|
||||
layout_args['yaxis']['title'] = _('BMI')
|
||||
|
||||
fig = go.Figure({
|
||||
'data': [trace],
|
||||
'layout': go.Layout(**layout_args)
|
||||
})
|
||||
output = plotly.plot(fig, output_type='div', include_plotlyjs=False)
|
||||
return utils.split_graph_output(output)
|
|
@ -0,0 +1,37 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
import plotly.offline as plotly
|
||||
import plotly.graph_objs as go
|
||||
|
||||
from reports import utils
|
||||
|
||||
|
||||
def head_circumference_head_circumference(objects):
|
||||
"""
|
||||
Create a graph showing head_circumference over time.
|
||||
:param objects: a QuerySet of Head Circumference instances.
|
||||
:returns: a tuple of the the graph's html and javascript.
|
||||
"""
|
||||
objects = objects.order_by('-date')
|
||||
|
||||
trace = go.Scatter(
|
||||
name=_('Head Circumference'),
|
||||
x=list(objects.values_list('date', flat=True)),
|
||||
y=list(objects.values_list('head_circumference', flat=True)),
|
||||
fill='tozeroy',
|
||||
)
|
||||
|
||||
layout_args = utils.default_graph_layout_options()
|
||||
layout_args['barmode'] = 'stack'
|
||||
layout_args['title'] = _('<b>Head Circumference</b>')
|
||||
layout_args['xaxis']['title'] = _('Date')
|
||||
layout_args['xaxis']['rangeselector'] = utils.rangeselector_date()
|
||||
layout_args['yaxis']['title'] = _('Head Circumference')
|
||||
|
||||
fig = go.Figure({
|
||||
'data': [trace],
|
||||
'layout': go.Layout(**layout_args)
|
||||
})
|
||||
output = plotly.plot(fig, output_type='div', include_plotlyjs=False)
|
||||
return utils.split_graph_output(output)
|
|
@ -0,0 +1,37 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
import plotly.offline as plotly
|
||||
import plotly.graph_objs as go
|
||||
|
||||
from reports import utils
|
||||
|
||||
|
||||
def height_height(objects):
|
||||
"""
|
||||
Create a graph showing height over time.
|
||||
:param objects: a QuerySet of Height instances.
|
||||
:returns: a tuple of the the graph's html and javascript.
|
||||
"""
|
||||
objects = objects.order_by('-date')
|
||||
|
||||
trace = go.Scatter(
|
||||
name=_('Height'),
|
||||
x=list(objects.values_list('date', flat=True)),
|
||||
y=list(objects.values_list('height', flat=True)),
|
||||
fill='tozeroy',
|
||||
)
|
||||
|
||||
layout_args = utils.default_graph_layout_options()
|
||||
layout_args['barmode'] = 'stack'
|
||||
layout_args['title'] = _('<b>Height</b>')
|
||||
layout_args['xaxis']['title'] = _('Date')
|
||||
layout_args['xaxis']['rangeselector'] = utils.rangeselector_date()
|
||||
layout_args['yaxis']['title'] = _('Height')
|
||||
|
||||
fig = go.Figure({
|
||||
'data': [trace],
|
||||
'layout': go.Layout(**layout_args)
|
||||
})
|
||||
output = plotly.plot(fig, output_type='div', include_plotlyjs=False)
|
||||
return utils.split_graph_output(output)
|
|
@ -0,0 +1,9 @@
|
|||
{% extends 'reports/report_base.html' %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}{% trans "BMI" %} - {{ object }}{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
{{ block.super }}
|
||||
<li class="breadcrumb-item active" aria-current="page">{% trans "BMI" %}</li>
|
||||
{% endblock %}
|
|
@ -0,0 +1,9 @@
|
|||
{% extends 'reports/report_base.html' %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}{% trans "Head Circumference" %} - {{ object }}{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
{{ block.super }}
|
||||
<li class="breadcrumb-item active" aria-current="page">{% trans "Head Circumference" %}</li>
|
||||
{% endblock %}
|
|
@ -0,0 +1,9 @@
|
|||
{% extends 'reports/report_base.html' %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}{% trans "Height" %} - {{ object }}{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
{{ block.super }}
|
||||
<li class="breadcrumb-item active" aria-current="page">{% trans "Height" %}</li>
|
||||
{% endblock %}
|
|
@ -52,3 +52,12 @@ class ViewsTestCase(TestCase):
|
|||
|
||||
page = self.c.get('{}/weight/weight/'.format(base_url))
|
||||
self.assertEqual(page.status_code, 200)
|
||||
|
||||
page = self.c.get('{}/height/height/'.format(base_url))
|
||||
self.assertEqual(page.status_code, 200)
|
||||
|
||||
page = self.c.get('{}/head-circumference/head-circumference/'.format(base_url))
|
||||
self.assertEqual(page.status_code, 200)
|
||||
|
||||
page = self.c.get('{}/bmi/bmi/'.format(base_url))
|
||||
self.assertEqual(page.status_code, 200)
|
||||
|
|
|
@ -51,4 +51,19 @@ urlpatterns = [
|
|||
views.WeightWeightChildReport.as_view(),
|
||||
name='report-weight-weight-child'
|
||||
),
|
||||
path(
|
||||
'children/<str:slug>/reports/height/height/',
|
||||
views.HeightHeightChildReport.as_view(),
|
||||
name='report-height-height-child'
|
||||
),
|
||||
path(
|
||||
'children/<str:slug>/reports/head-circumference/head-circumference/',
|
||||
views.HeadCircumferenceHeadCircumferenceChildReport.as_view(),
|
||||
name='report-head-circumference-head-circumference-child'
|
||||
),
|
||||
path(
|
||||
'children/<str:slug>/reports/bmi/bmi/',
|
||||
views.BMIBMIChildReport.as_view(),
|
||||
name='report-bmi-bmi-child'
|
||||
),
|
||||
]
|
||||
|
|
|
@ -195,3 +195,54 @@ class WeightWeightChildReport(PermissionRequiredMixin, DetailView):
|
|||
if objects:
|
||||
context['html'], context['js'] = graphs.weight_weight(objects)
|
||||
return context
|
||||
|
||||
class HeightHeightChildReport(PermissionRequiredMixin, DetailView):
|
||||
"""
|
||||
Graph of height change over time.
|
||||
"""
|
||||
model = models.Child
|
||||
permission_required = ('core.view_child',)
|
||||
template_name = 'reports/height_change.html'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(HeightHeightChildReport, self).get_context_data(
|
||||
**kwargs)
|
||||
child = context['object']
|
||||
objects = models.Height.objects.filter(child=child)
|
||||
if objects:
|
||||
context['html'], context['js'] = graphs.height_height(objects)
|
||||
return context
|
||||
|
||||
class HeadCircumferenceHeadCircumferenceChildReport(PermissionRequiredMixin, DetailView):
|
||||
"""
|
||||
Graph of head circumference change over time.
|
||||
"""
|
||||
model = models.Child
|
||||
permission_required = ('core.view_child',)
|
||||
template_name = 'reports/head_circumference_change.html'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(HeadCircumferenceHeadCircumferenceChildReport, self).get_context_data(
|
||||
**kwargs)
|
||||
child = context['object']
|
||||
objects = models.HeadCircumference.objects.filter(child=child)
|
||||
if objects:
|
||||
context['html'], context['js'] = graphs.head_circumference_head_circumference(objects)
|
||||
return context
|
||||
|
||||
class BMIBMIChildReport(PermissionRequiredMixin, DetailView):
|
||||
"""
|
||||
Graph of BMI change over time.
|
||||
"""
|
||||
model = models.Child
|
||||
permission_required = ('core.view_child',)
|
||||
template_name = 'reports/bmi_change.html'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(BMIBMIChildReport, self).get_context_data(
|
||||
**kwargs)
|
||||
child = context['object']
|
||||
objects = models.BMI.objects.filter(child=child)
|
||||
if objects:
|
||||
context['html'], context['js'] = graphs.bmi_bmi(objects)
|
||||
return context
|
Loading…
Reference in New Issue