mirror of https://github.com/snachodog/mybuddy.git
Add birth time support to Child model
This commit is contained in:
parent
0077d26142
commit
39c1e98d8c
|
@ -126,7 +126,15 @@ class PumpingSerializer(CoreModelSerializer, TaggableSerializer):
|
||||||
class ChildSerializer(serializers.HyperlinkedModelSerializer):
|
class ChildSerializer(serializers.HyperlinkedModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = models.Child
|
model = models.Child
|
||||||
fields = ("id", "first_name", "last_name", "birth_date", "slug", "picture")
|
fields = (
|
||||||
|
"id",
|
||||||
|
"first_name",
|
||||||
|
"last_name",
|
||||||
|
"birth_date",
|
||||||
|
"birth_time",
|
||||||
|
"slug",
|
||||||
|
"picture",
|
||||||
|
)
|
||||||
lookup_field = "slug"
|
lookup_field = "slug"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -139,13 +139,19 @@ class ChildAPITestCase(TestBase.BabyBuddyAPITestCaseBase):
|
||||||
"first_name": "Fake",
|
"first_name": "Fake",
|
||||||
"last_name": "Child",
|
"last_name": "Child",
|
||||||
"birth_date": "2017-11-11",
|
"birth_date": "2017-11-11",
|
||||||
|
"birth_time": None,
|
||||||
"slug": "fake-child",
|
"slug": "fake-child",
|
||||||
"picture": None,
|
"picture": None,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_post(self):
|
def test_post(self):
|
||||||
data = {"first_name": "Test", "last_name": "Child", "birth_date": "2017-11-12"}
|
data = {
|
||||||
|
"first_name": "Test",
|
||||||
|
"last_name": "Child",
|
||||||
|
"birth_date": "2017-11-12",
|
||||||
|
"birth_time": "23:25",
|
||||||
|
}
|
||||||
response = self.client.post(self.endpoint, data, format="json")
|
response = self.client.post(self.endpoint, data, format="json")
|
||||||
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
|
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
|
||||||
obj = models.Child.objects.get(pk=response.data["id"])
|
obj = models.Child.objects.get(pk=response.data["id"])
|
||||||
|
|
13
api/views.py
13
api/views.py
|
@ -33,9 +33,16 @@ class ChildViewSet(viewsets.ModelViewSet):
|
||||||
queryset = models.Child.objects.all()
|
queryset = models.Child.objects.all()
|
||||||
serializer_class = serializers.ChildSerializer
|
serializer_class = serializers.ChildSerializer
|
||||||
lookup_field = "slug"
|
lookup_field = "slug"
|
||||||
filterset_fields = ("id", "first_name", "last_name", "slug", "birth_date")
|
filterset_fields = (
|
||||||
ordering_fields = ("birth_date", "first_name", "last_name", "slug")
|
"id",
|
||||||
ordering = "-birth_date"
|
"first_name",
|
||||||
|
"last_name",
|
||||||
|
"slug",
|
||||||
|
"birth_date",
|
||||||
|
"birth_time",
|
||||||
|
)
|
||||||
|
ordering_fields = ("birth_date", "birth_time", "first_name", "last_name", "slug")
|
||||||
|
ordering = ["-birth_date", "-birth_time"]
|
||||||
|
|
||||||
|
|
||||||
class DiaperChangeViewSet(viewsets.ModelViewSet):
|
class DiaperChangeViewSet(viewsets.ModelViewSet):
|
||||||
|
|
|
@ -49,10 +49,10 @@ class ChildImportExportResource(resources.ModelResource):
|
||||||
|
|
||||||
@admin.register(models.Child)
|
@admin.register(models.Child)
|
||||||
class ChildAdmin(ImportExportMixin, ExportActionMixin, admin.ModelAdmin):
|
class ChildAdmin(ImportExportMixin, ExportActionMixin, admin.ModelAdmin):
|
||||||
list_display = ("first_name", "last_name", "birth_date", "slug")
|
list_display = ("first_name", "last_name", "birth_date", "birth_time", "slug")
|
||||||
list_filter = ("last_name",)
|
list_filter = ("last_name",)
|
||||||
search_fields = ("first_name", "last_name", "birth_date")
|
search_fields = ("first_name", "last_name", "birth_date")
|
||||||
fields = ["first_name", "last_name", "birth_date"]
|
fields = ["first_name", "last_name", "birth_date", "birth_time"]
|
||||||
if settings.BABY_BUDDY["ALLOW_UPLOADS"]:
|
if settings.BABY_BUDDY["ALLOW_UPLOADS"]:
|
||||||
fields.append("picture")
|
fields.append("picture")
|
||||||
resource_class = ChildImportExportResource
|
resource_class = ChildImportExportResource
|
||||||
|
|
|
@ -7,7 +7,7 @@ from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from taggit.forms import TagField
|
from taggit.forms import TagField
|
||||||
|
|
||||||
from babybuddy.widgets import DateInput, DateTimeInput
|
from babybuddy.widgets import DateInput, DateTimeInput, TimeInput
|
||||||
from core import models
|
from core import models
|
||||||
from core.widgets import TagsEditor, ChildRadioSelect
|
from core.widgets import TagsEditor, ChildRadioSelect
|
||||||
|
|
||||||
|
@ -107,11 +107,12 @@ class CoreModelForm(forms.ModelForm):
|
||||||
class ChildForm(forms.ModelForm):
|
class ChildForm(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = models.Child
|
model = models.Child
|
||||||
fields = ["first_name", "last_name", "birth_date"]
|
fields = ["first_name", "last_name", "birth_date", "birth_time"]
|
||||||
if settings.BABY_BUDDY["ALLOW_UPLOADS"]:
|
if settings.BABY_BUDDY["ALLOW_UPLOADS"]:
|
||||||
fields.append("picture")
|
fields.append("picture")
|
||||||
widgets = {
|
widgets = {
|
||||||
"birth_date": DateInput(),
|
"birth_date": DateInput(),
|
||||||
|
"birth_time": TimeInput(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
# Generated by Django 4.2.6 on 2023-10-21 17:45
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
("core", "0031_note_image"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="child",
|
||||||
|
name="birth_time",
|
||||||
|
field=models.TimeField(blank=True, null=True, verbose_name="Birth time"),
|
||||||
|
),
|
||||||
|
]
|
|
@ -1,4 +1,5 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
import datetime
|
||||||
import re
|
import re
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
|
||||||
|
@ -165,6 +166,7 @@ class Child(models.Model):
|
||||||
blank=True, max_length=255, verbose_name=_("Last name")
|
blank=True, max_length=255, verbose_name=_("Last name")
|
||||||
)
|
)
|
||||||
birth_date = models.DateField(blank=False, null=False, verbose_name=_("Birth date"))
|
birth_date = models.DateField(blank=False, null=False, verbose_name=_("Birth date"))
|
||||||
|
birth_time = models.TimeField(blank=True, null=True, verbose_name=_("Birth time"))
|
||||||
slug = models.SlugField(
|
slug = models.SlugField(
|
||||||
allow_unicode=True,
|
allow_unicode=True,
|
||||||
blank=False,
|
blank=False,
|
||||||
|
@ -206,6 +208,13 @@ class Child(models.Model):
|
||||||
return "{}, {}".format(self.last_name, self.first_name)
|
return "{}, {}".format(self.last_name, self.first_name)
|
||||||
return "{} {}".format(self.first_name, self.last_name)
|
return "{} {}".format(self.first_name, self.last_name)
|
||||||
|
|
||||||
|
def birth_datetime(self):
|
||||||
|
if self.birth_time:
|
||||||
|
return timezone.make_aware(
|
||||||
|
datetime.datetime.combine(self.birth_date, self.birth_time)
|
||||||
|
)
|
||||||
|
return self.birth_date
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def count(cls):
|
def count(cls):
|
||||||
"""Get a (cached) count of total number of Child instances."""
|
"""Get a (cached) count of total number of Child instances."""
|
||||||
|
|
|
@ -22,8 +22,8 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="child-name display-4">{{ object }}</div>
|
<div class="child-name display-4">{{ object }}</div>
|
||||||
<p class="lead">
|
<p class="lead">
|
||||||
{% trans "Born" %} <span class="text-secondary">{{ object.birth_date }}</span><br/>
|
{% trans "Born" %} <span class="text-secondary">{{ object.birth_datetime }}</span><br/>
|
||||||
{% trans "Age" %} <span class="text-secondary">{{ object.birth_date|child_age_string }}</span>
|
{% trans "Age" %} <span class="text-secondary">{{ object.birth_datetime|child_age_string }}</span>
|
||||||
</p>
|
</p>
|
||||||
{% include 'dashboard/child_button_group.html' %}
|
{% include 'dashboard/child_button_group.html' %}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
<a href="{% url 'core:child' child.slug %}">{{ child.first_name }}</a>
|
<a href="{% url 'core:child' child.slug %}">{{ child.first_name }}</a>
|
||||||
</th>
|
</th>
|
||||||
<td>{{ child.last_name }}</td>
|
<td>{{ child.last_name }}</td>
|
||||||
<td>{{ child.birth_date }}</td>
|
<td>{{ child.birth_datetime }}</td>
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
<div class="btn-group btn-group-sm" role="group" aria-label="{% trans "Actions" %}">
|
<div class="btn-group btn-group-sm" role="group" aria-label="{% trans "Actions" %}">
|
||||||
|
|
||||||
|
|
|
@ -20,9 +20,6 @@ def child_age_string(birth_date):
|
||||||
"""
|
"""
|
||||||
if not birth_date:
|
if not birth_date:
|
||||||
return ""
|
return ""
|
||||||
# Return "0 days" for anything under one day.
|
|
||||||
elif timezone.localdate() - birth_date < timezone.timedelta(days=1):
|
|
||||||
return _("0 days")
|
|
||||||
try:
|
try:
|
||||||
return timesince.timesince(birth_date, depth=1)
|
return timesince.timesince(birth_date, depth=1)
|
||||||
except (ValueError, TypeError):
|
except (ValueError, TypeError):
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
first_name,last_name,birth_date
|
first_name,last_name,birth_date,birth_time
|
||||||
Emily,Huerta,2020-01-17
|
Emily,Huerta,2020-01-17,10:21
|
||||||
|
|
|
|
@ -24,8 +24,8 @@ class TemplateTagsTestCase(TestCase):
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_child_age_string(self):
|
def test_child_age_string(self):
|
||||||
date = timezone.localdate() - timezone.timedelta(days=0, hours=6)
|
date = timezone.localtime() - timezone.timedelta(days=0, hours=6)
|
||||||
self.assertEqual("0 days", duration.child_age_string(date))
|
self.assertEqual("6\xa0hours", duration.child_age_string(date))
|
||||||
date = timezone.localdate() - timezone.timedelta(days=1, hours=6)
|
date = timezone.localdate() - timezone.timedelta(days=1, hours=6)
|
||||||
self.assertEqual("1\xa0day", duration.child_age_string(date))
|
self.assertEqual("1\xa0day", duration.child_age_string(date))
|
||||||
date = timezone.localdate() - timezone.timedelta(days=45)
|
date = timezone.localdate() - timezone.timedelta(days=45)
|
||||||
|
|
1045
openapi-schema.yml
1045
openapi-schema.yml
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue