mybuddy/core/forms.py

296 lines
8.9 KiB
Python
Raw Normal View History

# -*- coding: utf-8 -*-
from django import forms
2022-03-08 11:55:50 +00:00
from django.forms import widgets
from django.conf import settings
from django.utils import timezone
from django.utils.translation import gettext as _
from taggit.forms import TagField
from babybuddy.widgets import DateInput, DateTimeInput
2017-11-10 00:50:54 +00:00
from core import models
from core.widgets import TagsEditor, ChildRadioSelect
2022-02-27 19:00:12 +00:00
def set_initial_values(kwargs, form_type):
"""
Sets initial value for add forms based on provided kwargs.
:param kwargs: Keyword arguments.
:param form_type: Class of the type of form being initialized.
:return: Keyword arguments with updated "initial" values.
"""
# Never update initial values for existing instance (e.g. edit operation).
2022-02-10 00:00:30 +00:00
if kwargs.get("instance", None):
return kwargs
# Add the "initial" kwarg if it does not already exist.
2022-02-10 00:00:30 +00:00
if not kwargs.get("initial"):
kwargs.update(initial={})
# Set Child based on `child` kwarg or single Chile database.
2022-02-10 00:00:30 +00:00
child_slug = kwargs.get("child", None)
if child_slug:
2022-02-10 00:00:30 +00:00
kwargs["initial"].update(
{
"child": models.Child.objects.filter(slug=child_slug).first(),
}
)
elif models.Child.count() == 1:
2022-02-10 00:00:30 +00:00
kwargs["initial"].update({"child": models.Child.objects.first()})
# Set start and end time based on Timer from `timer` kwarg.
2022-02-10 00:00:30 +00:00
timer_id = kwargs.get("timer", None)
if timer_id:
timer = models.Timer.objects.get(id=timer_id)
2022-02-10 00:00:30 +00:00
kwargs["initial"].update(
{"timer": timer, "start": timer.start, "end": timezone.now()}
2022-02-10 00:00:30 +00:00
)
# Set type and method values for Feeding instance based on last feed.
2022-02-10 00:00:30 +00:00
if form_type == FeedingForm and "child" in kwargs["initial"]:
last_feeding = (
models.Feeding.objects.filter(child=kwargs["initial"]["child"])
.order_by("end")
.last()
)
if last_feeding:
last_method = last_feeding.method
2022-02-10 00:00:30 +00:00
last_feed_args = {"type": last_feeding.type}
if last_method not in ["left breast", "right breast"]:
last_feed_args["method"] = last_method
kwargs["initial"].update(last_feed_args)
# Set default "nap" value for Sleep instances.
if form_type == SleepForm and "nap" not in kwargs["initial"]:
try:
start = timezone.localtime(kwargs["initial"]["start"]).time()
except KeyError:
start = timezone.localtime().time()
nap = (
models.Sleep.settings.nap_start_min
<= start
<= models.Sleep.settings.nap_start_max
)
kwargs["initial"].update({"nap": nap})
# Remove custom kwargs, so they do not interfere with `super` calls.
2022-02-10 00:00:30 +00:00
for key in ["child", "timer"]:
try:
kwargs.pop(key)
except KeyError:
pass
return kwargs
class CoreModelForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
# Set `timer_id` so the Timer can be stopped in the `save` method.
2022-02-10 00:00:30 +00:00
self.timer_id = kwargs.get("timer", None)
kwargs = set_initial_values(kwargs, type(self))
super(CoreModelForm, self).__init__(*args, **kwargs)
def save(self, commit=True):
# If `timer_id` is present, stop the Timer.
instance = super(CoreModelForm, self).save(commit=False)
if self.timer_id:
timer = models.Timer.objects.get(id=self.timer_id)
timer.stop()
if commit:
instance.save()
2022-02-15 14:46:07 +00:00
self.save_m2m()
return instance
class ChildForm(forms.ModelForm):
class Meta:
2017-11-10 00:50:54 +00:00
model = models.Child
2022-02-10 00:00:30 +00:00
fields = ["first_name", "last_name", "birth_date"]
if settings.BABY_BUDDY["ALLOW_UPLOADS"]:
fields.append("picture")
widgets = {
"birth_date": DateInput(),
}
class ChildDeleteForm(forms.ModelForm):
confirm_name = forms.CharField(max_length=511)
class Meta:
2017-11-10 00:50:54 +00:00
model = models.Child
fields = []
def clean_confirm_name(self):
2022-02-10 00:00:30 +00:00
confirm_name = self.cleaned_data["confirm_name"]
if confirm_name != str(self.instance):
2017-11-01 20:14:42 +00:00
raise forms.ValidationError(
2022-02-10 00:00:30 +00:00
_("Name does not match child name."), code="confirm_mismatch"
)
return confirm_name
def save(self, commit=True):
instance = self.instance
self.instance.delete()
return instance
class TaggableModelForm(forms.ModelForm):
tags = TagField(
widget=TagsEditor,
required=False,
strip=True,
help_text=_(
"Click on the tags to add (+) or remove (-) tags or use the text editor to create new tags."
),
)
2023-01-28 14:14:23 +00:00
class PumpingForm(CoreModelForm, TaggableModelForm):
class Meta:
2022-03-04 15:39:13 +00:00
model = models.Pumping
fields = ["child", "start", "end", "amount", "notes", "tags"]
widgets = {
"child": ChildRadioSelect,
"start": DateTimeInput(),
"end": DateTimeInput(),
"notes": forms.Textarea(attrs={"rows": 5}),
}
class DiaperChangeForm(CoreModelForm, TaggableModelForm):
class Meta:
2017-11-10 00:50:54 +00:00
model = models.DiaperChange
2022-07-07 11:41:35 +00:00
fields = ["child", "time", "wet", "solid", "color", "amount", "notes", "tags"]
widgets = {
"child": ChildRadioSelect(),
"time": DateTimeInput(),
2022-02-10 00:00:30 +00:00
"notes": forms.Textarea(attrs={"rows": 5}),
}
class FeedingForm(CoreModelForm, TaggableModelForm):
class Meta:
2017-11-10 00:50:54 +00:00
model = models.Feeding
2022-07-07 11:41:35 +00:00
fields = ["child", "start", "end", "type", "method", "amount", "notes", "tags"]
widgets = {
"child": ChildRadioSelect,
"start": DateTimeInput(),
"end": DateTimeInput(),
2022-02-10 00:00:30 +00:00
"notes": forms.Textarea(attrs={"rows": 5}),
}
class NoteForm(CoreModelForm, TaggableModelForm):
2017-11-10 00:50:54 +00:00
class Meta:
model = models.Note
2022-02-15 09:13:35 +00:00
fields = ["child", "note", "time", "tags"]
widgets = {
"child": ChildRadioSelect,
"time": DateTimeInput(),
}
2017-11-10 00:50:54 +00:00
class SleepForm(CoreModelForm, TaggableModelForm):
class Meta:
2017-11-10 00:50:54 +00:00
model = models.Sleep
fields = ["child", "start", "end", "nap", "notes", "tags"]
widgets = {
"child": ChildRadioSelect,
"start": DateTimeInput(),
"end": DateTimeInput(),
2022-02-10 00:00:30 +00:00
"notes": forms.Textarea(attrs={"rows": 5}),
}
class TemperatureForm(CoreModelForm, TaggableModelForm):
2019-05-17 04:33:26 +00:00
class Meta:
model = models.Temperature
fields = ["child", "temperature", "time", "notes", "tags"]
2019-05-17 04:33:26 +00:00
widgets = {
"child": ChildRadioSelect,
"time": DateTimeInput(),
2022-02-10 00:00:30 +00:00
"notes": forms.Textarea(attrs={"rows": 5}),
2019-05-17 04:33:26 +00:00
}
class TimerForm(CoreModelForm):
2017-08-17 01:57:01 +00:00
class Meta:
2017-11-10 00:50:54 +00:00
model = models.Timer
2022-02-10 00:00:30 +00:00
fields = ["child", "name", "start"]
widgets = {
"child": ChildRadioSelect,
"start": DateTimeInput(),
}
2017-08-17 01:57:01 +00:00
def __init__(self, *args, **kwargs):
2022-02-10 00:00:30 +00:00
self.user = kwargs.pop("user")
super(TimerForm, self).__init__(*args, **kwargs)
def save(self, commit=True):
instance = super(TimerForm, self).save(commit=False)
2017-09-10 13:50:16 +00:00
instance.user = self.user
instance.save()
return instance
2017-08-17 01:57:01 +00:00
class TummyTimeForm(CoreModelForm, TaggableModelForm):
class Meta:
2017-11-10 00:50:54 +00:00
model = models.TummyTime
fields = ["child", "start", "end", "milestone", "tags"]
widgets = {
"child": ChildRadioSelect,
"start": DateTimeInput(),
"end": DateTimeInput(),
}
2017-11-10 02:15:09 +00:00
class WeightForm(CoreModelForm, TaggableModelForm):
2017-11-10 02:15:09 +00:00
class Meta:
model = models.Weight
fields = ["child", "weight", "date", "notes", "tags"]
2017-11-10 02:15:09 +00:00
widgets = {
"child": ChildRadioSelect,
"date": DateInput(),
2022-02-10 00:00:30 +00:00
"notes": forms.Textarea(attrs={"rows": 5}),
2017-11-10 02:15:09 +00:00
}
2021-12-30 03:32:55 +00:00
class HeightForm(CoreModelForm, TaggableModelForm):
class Meta:
model = models.Height
fields = ["child", "height", "date", "notes", "tags"]
widgets = {
"child": ChildRadioSelect,
"date": DateInput(),
2022-02-10 00:00:30 +00:00
"notes": forms.Textarea(attrs={"rows": 5}),
}
2021-12-30 03:32:55 +00:00
class HeadCircumferenceForm(CoreModelForm, TaggableModelForm):
class Meta:
model = models.HeadCircumference
fields = ["child", "head_circumference", "date", "notes", "tags"]
widgets = {
"child": ChildRadioSelect,
"date": DateInput(),
2022-02-10 00:00:30 +00:00
"notes": forms.Textarea(attrs={"rows": 5}),
}
2021-12-30 03:32:55 +00:00
class BMIForm(CoreModelForm, TaggableModelForm):
class Meta:
model = models.BMI
fields = ["child", "bmi", "date", "notes", "tags"]
widgets = {
"child": ChildRadioSelect,
"date": DateInput(),
2022-02-10 00:00:30 +00:00
"notes": forms.Textarea(attrs={"rows": 5}),
2021-12-30 03:32:55 +00:00
}
2022-03-08 11:55:50 +00:00
class TagAdminForm(forms.ModelForm):
class Meta:
widgets = {"color": widgets.TextInput(attrs={"type": "color"})}