mybuddy/core/forms.py

239 lines
7.4 KiB
Python

# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django import forms
from django.utils import timezone
from .models import Child, DiaperChange, Feeding, Sleep, Timer, TummyTime
# Sets the default Child instance if only one exists in the database.
def set_default_child(kwargs):
instance = kwargs.get('instance', None)
if not kwargs.get('initial'):
kwargs.update(initial={})
if instance is None and Child.objects.count() == 1:
kwargs['initial'].update({'child': Child.objects.first()})
return kwargs
# Uses a timer to set the default start and end date and updates the timer.
def set_default_duration(kwargs):
instance = kwargs.get('instance', None)
timer_id = kwargs.get('timer', None)
if not kwargs.get('initial'):
kwargs.update(initial={})
if not instance and timer_id:
instance = Timer.objects.get(id=timer_id)
kwargs['initial'].update({
'timer': instance,
'start': instance.start,
'end': instance.end or timezone.now()
})
try:
kwargs.pop('timer')
except KeyError:
pass
return kwargs
class ChildForm(forms.ModelForm):
class Meta:
model = Child
fields = ['first_name', 'last_name', 'birth_date']
widgets = {
'birth_date': forms.DateInput(attrs={
'class': 'datepicker-input',
'data-target': '#datetimepicker_date',
}),
}
class ChildDeleteForm(forms.ModelForm):
confirm_name = forms.CharField(max_length=511)
class Meta:
model = 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.')
return confirm_name
def save(self, commit=True):
instance = self.instance
self.instance.delete()
return instance
class DiaperChangeForm(forms.ModelForm):
class Meta:
model = DiaperChange
fields = ['child', 'time', 'wet', 'solid', 'color']
widgets = {
'time': forms.DateTimeInput(attrs={
'class': 'datepicker-input',
'data-target': '#datetimepicker_time',
}),
}
def __init__(self, *args, **kwargs):
kwargs = set_default_child(kwargs)
super(DiaperChangeForm, self).__init__(*args, **kwargs)
def clean(self):
"""Additional form validation/cleaning.
"""
errors = {}
# One or both of Wet and Solid is required.
if not self.cleaned_data['wet'] and not self.cleaned_data['solid']:
errors['wet'] = forms.ValidationError(
'Wet and/or solid is required.',
code='missing-wet-or-solid')
errors['solid'] = forms.ValidationError(
'Wet and/or solid is required.',
code='missing-wet-or-solid')
# Color is required when Solid is selected.
if self.cleaned_data['solid'] and not self.cleaned_data['color']:
errors['color'] = forms.ValidationError(
'Color is required for solid changes.',
code='missing-color')
if len(errors) > 0:
raise forms.ValidationError(errors)
return self.cleaned_data
class FeedingForm(forms.ModelForm):
class Meta:
model = Feeding
fields = ['child', 'start', 'end', 'type', 'method', 'amount']
widgets = {
'start': forms.DateTimeInput(attrs={
'class': 'datepicker-input',
'data-target': '#datetimepicker_start',
}),
'end': forms.DateTimeInput(attrs={
'class': 'datepicker-input',
'data-target': '#datetimepicker_end',
}),
}
def __init__(self, *args, **kwargs):
kwargs = set_default_child(kwargs)
self.timer_id = kwargs.get('timer', None)
kwargs = set_default_duration(kwargs)
super(FeedingForm, self).__init__(*args, **kwargs)
def clean(self):
"""Additional form validation/cleaning.
"""
errors = {}
# "Formula" Type may only be associated with "Bottle" Method.
if (self.cleaned_data['type'] == 'formula'
and self.cleaned_data['method'] != 'bottle'):
errors['method'] = forms.ValidationError(
'Only "Bottle" method is allowed with type "Formula".',
code='bottle-formula-mismatch')
if len(errors) > 0:
raise forms.ValidationError(errors)
return self.cleaned_data
def save(self, commit=True):
instance = super(FeedingForm, self).save(commit=False)
if self.timer_id:
timer = Timer.objects.get(id=self.timer_id)
timer.stop(instance.end)
instance.save()
return instance
class SleepForm(forms.ModelForm):
class Meta:
model = Sleep
fields = ['child', 'start', 'end']
widgets = {
'start': forms.DateTimeInput(attrs={
'class': 'datepicker-input',
'data-target': '#datetimepicker_start',
}),
'end': forms.DateTimeInput(attrs={
'class': 'datepicker-input',
'data-target': '#datetimepicker_end',
}),
}
def __init__(self, *args, **kwargs):
kwargs = set_default_child(kwargs)
self.timer_id = kwargs.get('timer', None)
kwargs = set_default_duration(kwargs)
super(SleepForm, self).__init__(*args, **kwargs)
def save(self, commit=True):
instance = super(SleepForm, self).save(commit=False)
if self.timer_id:
timer = Timer.objects.get(id=self.timer_id)
timer.stop(instance.end)
instance.save()
return instance
class TimerForm(forms.ModelForm):
class Meta:
model = Timer
fields = ['name', 'start']
widgets = {
'start': forms.DateTimeInput(attrs={
'class': 'datepicker-input',
'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(forms.ModelForm):
class Meta:
model = TummyTime
fields = ['child', 'start', 'end', 'milestone']
widgets = {
'start': forms.DateTimeInput(attrs={
'class': 'datepicker-input',
'data-target': '#datetimepicker_start',
}),
'end': forms.DateTimeInput(attrs={
'class': 'datepicker-input',
'data-target': '#datetimepicker_end',
}),
}
def __init__(self, *args, **kwargs):
kwargs = set_default_child(kwargs)
self.timer_id = kwargs.get('timer', None)
kwargs = set_default_duration(kwargs)
super(TummyTimeForm, self).__init__(*args, **kwargs)
def save(self, commit=True):
instance = super(TummyTimeForm, self).save(commit=False)
if self.timer_id:
timer = Timer.objects.get(id=self.timer_id)
timer.stop(instance.end)
instance.save()
return instance