mybuddy/core/forms.py

244 lines
7.4 KiB
Python

# -*- coding: utf-8 -*-
from django import forms
from django.conf import settings
from django.utils import timezone
from django.utils.translation import gettext as _
from core import models
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).
if kwargs.get('instance', None):
return kwargs
# Add the "initial" kwarg if it does not already exist.
if not kwargs.get('initial'):
kwargs.update(initial={})
# Set Child based on `child` kwarg or single Chile database.
child_slug = kwargs.get('child', None)
if child_slug:
kwargs['initial'].update({
'child': models.Child.objects.filter(slug=child_slug).first(),
})
elif models.Child.count() == 1:
kwargs['initial'].update({'child': models.Child.objects.first()})
# Set start and end time based on Timer from `timer` kwarg.
timer_id = kwargs.get('timer', None)
if timer_id:
timer = models.Timer.objects.get(id=timer_id)
kwargs['initial'].update({
'timer': timer,
'start': timer.start,
'end': timer.end or timezone.now()
})
# Set type and method values for Feeding instance based on last feed.
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
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)
# Remove custom kwargs so they do not interfere with `super` calls.
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.
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(instance.end)
if commit:
instance.save()
return instance
class ChildForm(forms.ModelForm):
class Meta:
model = models.Child
fields = [
'first_name',
'last_name',
'birth_date'
]
if settings.BABY_BUDDY['ALLOW_UPLOADS']:
fields.append('picture')
widgets = {
'birth_date': forms.DateInput(attrs={
'autocomplete': 'off',
'data-target': '#datetimepicker_date',
}),
}
class ChildDeleteForm(forms.ModelForm):
confirm_name = forms.CharField(max_length=511)
class Meta:
model = models.Child
fields = []
def clean_confirm_name(self):
confirm_name = self.cleaned_data['confirm_name']
if confirm_name != str(self.instance):
raise forms.ValidationError(
_('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 DiaperChangeForm(CoreModelForm):
class Meta:
model = models.DiaperChange
fields = ['child', 'time', 'wet', 'solid', 'color', 'amount', 'notes']
widgets = {
'time': forms.DateTimeInput(attrs={
'autocomplete': 'off',
'data-target': '#datetimepicker_time',
}),
'notes': forms.Textarea(attrs={'rows': 5}),
}
class FeedingForm(CoreModelForm):
class Meta:
model = models.Feeding
fields = ['child', 'start', 'end', 'type', 'method', 'amount', 'notes']
widgets = {
'start': forms.DateTimeInput(attrs={
'autocomplete': 'off',
'data-target': '#datetimepicker_start',
}),
'end': forms.DateTimeInput(attrs={
'autocomplete': 'off',
'data-target': '#datetimepicker_end',
}),
'notes': forms.Textarea(attrs={'rows': 5}),
}
class NoteForm(CoreModelForm):
class Meta:
model = models.Note
fields = ['child', 'note', 'time']
widgets = {
'time': forms.DateTimeInput(attrs={
'autocomplete': 'off',
'data-target': '#datetimepicker_time',
}),
}
class SleepForm(CoreModelForm):
class Meta:
model = models.Sleep
fields = ['child', 'start', 'end', 'notes']
widgets = {
'start': forms.DateTimeInput(attrs={
'autocomplete': 'off',
'data-target': '#datetimepicker_start',
}),
'end': forms.DateTimeInput(attrs={
'autocomplete': 'off',
'data-target': '#datetimepicker_end',
}),
'notes': forms.Textarea(attrs={'rows': 5}),
}
class TemperatureForm(CoreModelForm):
class Meta:
model = models.Temperature
fields = ['child', 'temperature', 'time', 'notes']
widgets = {
'time': forms.DateTimeInput(attrs={
'autocomplete': 'off',
'data-target': '#datetimepicker_time',
}),
'notes': forms.Textarea(attrs={'rows': 5}),
}
class TimerForm(CoreModelForm):
class Meta:
model = models.Timer
fields = ['child', 'name', 'start']
widgets = {
'start': forms.DateTimeInput(attrs={
'autocomplete': 'off',
'data-target': '#datetimepicker_start',
})
}
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user')
super(TimerForm, self).__init__(*args, **kwargs)
def save(self, commit=True):
instance = super(TimerForm, self).save(commit=False)
instance.user = self.user
instance.save()
return instance
class TummyTimeForm(CoreModelForm):
class Meta:
model = models.TummyTime
fields = ['child', 'start', 'end', 'milestone']
widgets = {
'start': forms.DateTimeInput(attrs={
'autocomplete': 'off',
'data-target': '#datetimepicker_start',
}),
'end': forms.DateTimeInput(attrs={
'autocomplete': 'off',
'data-target': '#datetimepicker_end',
}),
}
class WeightForm(CoreModelForm):
class Meta:
model = models.Weight
fields = ['child', 'weight', 'date', 'notes']
widgets = {
'date': forms.DateInput(attrs={
'autocomplete': 'off',
'data-target': '#datetimepicker_date',
}),
'notes': forms.Textarea(attrs={'rows': 5}),
}