39586-vm/core/forms.py
2026-04-12 12:41:59 +00:00

115 lines
5.5 KiB
Python

from django import forms
from django.utils import timezone
from .models import Event, Registration
class EventSearchForm(forms.Form):
q = forms.CharField(
required=False,
max_length=80,
label='Search',
widget=forms.TextInput(
attrs={
'placeholder': 'Search by title, venue, or keyword',
'class': 'form-control form-control-lg',
}
),
)
class RegistrationForm(forms.ModelForm):
class Meta:
model = Registration
fields = ['full_name', 'email', 'company', 'notes']
widgets = {
'full_name': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Jordan Lee'}),
'email': forms.EmailInput(attrs={'class': 'form-control', 'placeholder': 'you@example.com'}),
'company': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Studio North'}),
'notes': forms.Textarea(attrs={'class': 'form-control', 'rows': 4, 'placeholder': 'Accessibility needs, dietary notes, or questions'}),
}
def __init__(self, *args, event=None, **kwargs):
self.event = event
super().__init__(*args, **kwargs)
for field in self.fields.values():
css = field.widget.attrs.get('class', '')
if 'form-control' not in css:
field.widget.attrs['class'] = f'{css} form-control'.strip()
def clean_email(self):
email = self.cleaned_data['email'].strip().lower()
if self.event and Registration.objects.filter(event=self.event, email__iexact=email).exists():
raise forms.ValidationError('This email is already registered for this event.')
return email
class OrganizerEventForm(forms.ModelForm):
datetime_format = '%Y-%m-%dT%H:%M'
class Meta:
model = Event
fields = [
'title',
'summary',
'description',
'venue',
'start_at',
'end_at',
'capacity',
'is_published',
'registration_opens',
'registration_closes',
]
widgets = {
'title': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Spring Product Launch'}),
'summary': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'A short one-line overview for the catalog card.'}),
'description': forms.Textarea(attrs={'class': 'form-control', 'rows': 6, 'placeholder': 'Describe the agenda, audience, and what attendees should expect.'}),
'venue': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Northstar Studio, Austin'}),
'start_at': forms.DateTimeInput(format='%Y-%m-%dT%H:%M', attrs={'class': 'form-control', 'type': 'datetime-local'}),
'end_at': forms.DateTimeInput(format='%Y-%m-%dT%H:%M', attrs={'class': 'form-control', 'type': 'datetime-local'}),
'capacity': forms.NumberInput(attrs={'class': 'form-control', 'placeholder': 'Optional'}),
'is_published': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
'registration_opens': forms.DateTimeInput(format='%Y-%m-%dT%H:%M', attrs={'class': 'form-control', 'type': 'datetime-local'}),
'registration_closes': forms.DateTimeInput(format='%Y-%m-%dT%H:%M', attrs={'class': 'form-control', 'type': 'datetime-local'}),
}
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for field_name in ('start_at', 'end_at', 'registration_opens', 'registration_closes'):
self.fields[field_name].input_formats = [self.datetime_format]
value = self.initial.get(field_name)
if value:
self.initial[field_name] = timezone.localtime(value).strftime(self.datetime_format)
for field in self.fields.values():
css = field.widget.attrs.get('class', '')
if isinstance(field.widget, forms.CheckboxInput):
field.widget.attrs['class'] = 'form-check-input'
elif 'form-control' not in css:
field.widget.attrs['class'] = f'{css} form-control'.strip()
self.fields['capacity'].required = False
self.fields['registration_opens'].required = False
self.fields['registration_closes'].required = False
self.fields['is_published'].required = False
def clean(self):
cleaned_data = super().clean()
start_at = cleaned_data.get('start_at')
end_at = cleaned_data.get('end_at')
registration_opens = cleaned_data.get('registration_opens')
registration_closes = cleaned_data.get('registration_closes')
capacity = cleaned_data.get('capacity')
if start_at and end_at and end_at <= start_at:
self.add_error('end_at', 'End time must be after the event start time.')
if registration_opens and start_at and registration_opens > start_at:
self.add_error('registration_opens', 'Registration should open before the event begins.')
if registration_closes and start_at and registration_closes > start_at:
self.add_error('registration_closes', 'Registration should close before the event begins.')
if registration_opens and registration_closes and registration_closes <= registration_opens:
self.add_error('registration_closes', 'Registration close must be after registration open.')
if capacity is not None and capacity < 1:
self.add_error('capacity', 'Capacity must be at least 1 when provided.')
return cleaned_data