Refactor core forms on a base class to handle initial values

This commit is contained in:
Christopher C. Wells 2020-01-29 10:50:23 -08:00 committed by Christopher Charbonneau Wells
parent 4e01365e85
commit 3eb0e336c6
2 changed files with 65 additions and 119 deletions

View File

@ -7,21 +7,25 @@ from django.utils.translation import gettext as _
from core import models from core import models
def set_default_child(kwargs): def set_initial_values(kwargs, form_type):
""" """
Sets the default Child for an instance based on the `child` parameter or Sets initial value for add forms based on provided kwargs.
if only one Child instance exists.
:param kwargs: Form arguments. :param kwargs: Keyword arguments.
:return: Form arguments with updated initial values. :param form_type: Class of the type of form being initialized.
:return: Keyword arguments with updated "initial" values.
""" """
instance = kwargs.get('instance', None)
child_slug = kwargs.get('child', None) # 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'): if not kwargs.get('initial'):
kwargs.update(initial={}) kwargs.update(initial={})
# Do not update initial values for an existing instance (edit operation). # Set Child based on `child` kwarg or single Chile database.
if instance is None: child_slug = kwargs.get('child', None)
if child_slug: if child_slug:
kwargs['initial'].update({ kwargs['initial'].update({
'child': models.Child.objects.filter(slug=child_slug).first(), 'child': models.Child.objects.filter(slug=child_slug).first(),
@ -29,22 +33,9 @@ def set_default_child(kwargs):
elif models.Child.count() == 1: elif models.Child.count() == 1:
kwargs['initial'].update({'child': models.Child.objects.first()}) kwargs['initial'].update({'child': models.Child.objects.first()})
try: # Set start and end time based on Timer from `timer` kwarg.
kwargs.pop('child')
except KeyError:
pass
return kwargs
# Sets default values (start/end date, child) from a timer.
def set_defaults_from_timer(kwargs):
instance = kwargs.get('instance', None)
timer_id = kwargs.get('timer', None) timer_id = kwargs.get('timer', None)
if not kwargs.get('initial'): if timer_id:
kwargs.update(initial={})
# Do not update initial values for an existing instance (edit operation).
if not instance and timer_id:
timer = models.Timer.objects.get(id=timer_id) timer = models.Timer.objects.get(id=timer_id)
kwargs['initial'].update({ kwargs['initial'].update({
'timer': timer, 'timer': timer,
@ -52,26 +43,39 @@ def set_defaults_from_timer(kwargs):
'end': timer.end or timezone.now() 'end': timer.end or timezone.now()
}) })
# Set initial type value for Feeding instance based on last type used.
if form_type == FeedingForm and 'child' in kwargs['initial']:
last_feeding = models.Feeding.objects.filter(
child=kwargs['initial']['child']).latest('end')
if last_feeding:
kwargs['initial'].update({'type': last_feeding.type})
# Remove custom kwargs so they do not interfere with `super` calls.
for key in ['child', 'timer']:
try: try:
kwargs.pop('timer') kwargs.pop(key)
except KeyError: except KeyError:
pass pass
return kwargs return kwargs
# Sets the default Feeding type to the one used in the most recent entry. class CoreModelForm(forms.ModelForm):
def set_default_feeding_type(kwargs): def __init__(self, *args, **kwargs):
instance = kwargs.get('instance', None) # Set `timer_id` so the Timer can be stopped in the `save` method.
initial = kwargs.get('initial', None) self.timer_id = kwargs.get('timer', None)
if not kwargs.get('initial'): kwargs = set_initial_values(kwargs, type(self))
kwargs.update(initial={}) super(CoreModelForm, self).__init__(*args, **kwargs)
if instance is None and initial and 'child' in initial:
if models.Feeding.objects.filter(child=initial['child']).count() > 0: def save(self, commit=True):
kwargs['initial'].update({ # If `timer_id` is present, stop the Timer.
'type': models.Feeding.objects.filter( instance = super(CoreModelForm, self).save(commit=False)
child=initial['child']).latest('end').type if self.timer_id:
}) timer = models.Timer.objects.get(id=self.timer_id)
return kwargs timer.stop(instance.end)
if commit:
instance.save()
return instance
class ChildForm(forms.ModelForm): class ChildForm(forms.ModelForm):
@ -112,7 +116,7 @@ class ChildDeleteForm(forms.ModelForm):
return instance return instance
class DiaperChangeForm(forms.ModelForm): class DiaperChangeForm(CoreModelForm):
class Meta: class Meta:
model = models.DiaperChange model = models.DiaperChange
fields = ['child', 'time', 'wet', 'solid', 'color', 'amount'] fields = ['child', 'time', 'wet', 'solid', 'color', 'amount']
@ -123,12 +127,8 @@ class DiaperChangeForm(forms.ModelForm):
}), }),
} }
def __init__(self, *args, **kwargs):
kwargs = set_default_child(kwargs)
super(DiaperChangeForm, self).__init__(*args, **kwargs)
class FeedingForm(CoreModelForm):
class FeedingForm(forms.ModelForm):
class Meta: class Meta:
model = models.Feeding model = models.Feeding
fields = ['child', 'start', 'end', 'type', 'method', 'amount'] fields = ['child', 'start', 'end', 'type', 'method', 'amount']
@ -143,33 +143,14 @@ class FeedingForm(forms.ModelForm):
}), }),
} }
def __init__(self, *args, **kwargs):
kwargs = set_default_child(kwargs)
self.timer_id = kwargs.get('timer', None)
kwargs = set_defaults_from_timer(kwargs)
kwargs = set_default_feeding_type(kwargs)
super(FeedingForm, self).__init__(*args, **kwargs)
def save(self, commit=True): class NoteForm(CoreModelForm):
instance = super(FeedingForm, self).save(commit=False)
if self.timer_id:
timer = models.Timer.objects.get(id=self.timer_id)
timer.stop(instance.end)
instance.save()
return instance
class NoteForm(forms.ModelForm):
class Meta: class Meta:
model = models.Note model = models.Note
fields = ['child', 'note'] fields = ['child', 'note']
def __init__(self, *args, **kwargs):
kwargs = set_default_child(kwargs)
super(NoteForm, self).__init__(*args, **kwargs)
class SleepForm(CoreModelForm):
class SleepForm(forms.ModelForm):
class Meta: class Meta:
model = models.Sleep model = models.Sleep
fields = ['child', 'start', 'end'] fields = ['child', 'start', 'end']
@ -184,22 +165,8 @@ class SleepForm(forms.ModelForm):
}), }),
} }
def __init__(self, *args, **kwargs):
kwargs = set_default_child(kwargs)
self.timer_id = kwargs.get('timer', None)
kwargs = set_defaults_from_timer(kwargs)
super(SleepForm, self).__init__(*args, **kwargs)
def save(self, commit=True): class TemperatureForm(CoreModelForm):
instance = super(SleepForm, self).save(commit=False)
if self.timer_id:
timer = models.Timer.objects.get(id=self.timer_id)
timer.stop(instance.end)
instance.save()
return instance
class TemperatureForm(forms.ModelForm):
class Meta: class Meta:
model = models.Temperature model = models.Temperature
fields = ['child', 'temperature', 'time'] fields = ['child', 'temperature', 'time']
@ -210,12 +177,8 @@ class TemperatureForm(forms.ModelForm):
}), }),
} }
def __init__(self, *args, **kwargs):
kwargs = set_default_child(kwargs)
super(TemperatureForm, self).__init__(*args, **kwargs)
class TimerForm(CoreModelForm):
class TimerForm(forms.ModelForm):
class Meta: class Meta:
model = models.Timer model = models.Timer
fields = ['child', 'name', 'start'] fields = ['child', 'name', 'start']
@ -228,7 +191,6 @@ class TimerForm(forms.ModelForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user') self.user = kwargs.pop('user')
kwargs = set_default_child(kwargs)
super(TimerForm, self).__init__(*args, **kwargs) super(TimerForm, self).__init__(*args, **kwargs)
def save(self, commit=True): def save(self, commit=True):
@ -238,7 +200,7 @@ class TimerForm(forms.ModelForm):
return instance return instance
class TummyTimeForm(forms.ModelForm): class TummyTimeForm(CoreModelForm):
class Meta: class Meta:
model = models.TummyTime model = models.TummyTime
fields = ['child', 'start', 'end', 'milestone'] fields = ['child', 'start', 'end', 'milestone']
@ -253,22 +215,8 @@ class TummyTimeForm(forms.ModelForm):
}), }),
} }
def __init__(self, *args, **kwargs):
kwargs = set_default_child(kwargs)
self.timer_id = kwargs.get('timer', None)
kwargs = set_defaults_from_timer(kwargs)
super(TummyTimeForm, self).__init__(*args, **kwargs)
def save(self, commit=True): class WeightForm(CoreModelForm):
instance = super(TummyTimeForm, self).save(commit=False)
if self.timer_id:
timer = models.Timer.objects.get(id=self.timer_id)
timer.stop(instance.end)
instance.save()
return instance
class WeightForm(forms.ModelForm):
class Meta: class Meta:
model = models.Weight model = models.Weight
fields = ['child', 'weight', 'date'] fields = ['child', 'weight', 'date']
@ -278,7 +226,3 @@ class WeightForm(forms.ModelForm):
'data-target': '#datetimepicker_date', 'data-target': '#datetimepicker_date',
}), }),
} }
def __init__(self, *args, **kwargs):
kwargs = set_default_child(kwargs)
super(WeightForm, self).__init__(*args, **kwargs)

View File

@ -34,8 +34,10 @@ class CoreAddView(PermissionRequired403Mixin, SuccessMessageMixin, CreateView):
:return: Updated keyword arguments. :return: Updated keyword arguments.
""" """
kwargs = super(CoreAddView, self).get_form_kwargs() kwargs = super(CoreAddView, self).get_form_kwargs()
kwargs.update({'child': self.request.GET.get('child', None)}) for parameter in ['child', 'timer']:
kwargs.update({'timer': self.request.GET.get('timer', None)}) value = self.request.GET.get(parameter, None)
if value:
kwargs.update({parameter: value})
return kwargs return kwargs