Plant-level watering/sunlight fields override the species defaults. Rendered as btn-check radio buttons in the edit form; detail page shows the plant value (with emoji) falling back to species data. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
73 lines
2.6 KiB
Python
73 lines
2.6 KiB
Python
from django import forms
|
|
from .models import Plant, PruningLog, Location, WATERING_CHOICES, SUNLIGHT_CHOICES
|
|
|
|
MONTH_CHOICES = [
|
|
('1', 'Jan'), ('2', 'Feb'), ('3', 'Mar'), ('4', 'Apr'),
|
|
('5', 'May'), ('6', 'Jun'), ('7', 'Jul'), ('8', 'Aug'),
|
|
('9', 'Sep'), ('10', 'Oct'), ('11', 'Nov'), ('12', 'Dec'),
|
|
]
|
|
|
|
|
|
class PlantForm(forms.ModelForm):
|
|
bloom_months = forms.MultipleChoiceField(
|
|
choices=MONTH_CHOICES,
|
|
widget=forms.CheckboxSelectMultiple,
|
|
required=False,
|
|
label='Bloom months',
|
|
)
|
|
location = forms.ModelChoiceField(
|
|
queryset=Location.objects.all(),
|
|
required=False,
|
|
empty_label='— select location —',
|
|
widget=forms.Select(attrs={'class': 'form-select'}),
|
|
)
|
|
new_location = forms.CharField(
|
|
max_length=200,
|
|
required=False,
|
|
label='Or add new location',
|
|
widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'e.g. Living room'}),
|
|
)
|
|
watering = forms.ChoiceField(
|
|
choices=[('', '—')] + WATERING_CHOICES,
|
|
required=False,
|
|
)
|
|
sunlight = forms.ChoiceField(
|
|
choices=[('', '—')] + SUNLIGHT_CHOICES,
|
|
required=False,
|
|
)
|
|
|
|
class Meta:
|
|
model = Plant
|
|
fields = ['name', 'location', 'is_indoor', 'watering', 'sunlight', 'bloom_months', 'notes']
|
|
widgets = {
|
|
'notes': forms.Textarea(attrs={'rows': 3, 'class': 'form-control'}),
|
|
'name': forms.TextInput(attrs={'class': 'form-control'}),
|
|
}
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
if self.instance.pk and self.instance.bloom_months:
|
|
self.initial['bloom_months'] = [str(m) for m in self.instance.bloom_months]
|
|
elif not self.instance.pk and self.initial.get('bloom_months'):
|
|
self.initial['bloom_months'] = [str(m) for m in self.initial['bloom_months']]
|
|
|
|
def clean_bloom_months(self):
|
|
return [int(m) for m in self.cleaned_data.get('bloom_months', [])]
|
|
|
|
def clean(self):
|
|
cleaned = super().clean()
|
|
new_loc = cleaned.get('new_location', '').strip()
|
|
if new_loc:
|
|
loc, _ = Location.objects.get_or_create(name=new_loc)
|
|
cleaned['location'] = loc
|
|
return cleaned
|
|
|
|
|
|
class PruningLogForm(forms.ModelForm):
|
|
class Meta:
|
|
model = PruningLog
|
|
fields = ['pruned_on', 'notes']
|
|
widgets = {
|
|
'pruned_on': forms.DateInput(attrs={'type': 'date', 'class': 'form-control'}),
|
|
'notes': forms.Textarea(attrs={'rows': 2, 'class': 'form-control'}),
|
|
}
|