Add start/end time fields to CalendarEvent.
Closes #28. Replace hardcoded calendar times with admin-editable start_time/end_time so event cards show real schedules.
This commit is contained in:
@@ -165,10 +165,23 @@ class CalendarEventAdmin(admin.ModelAdmin):
|
||||
list_display = [
|
||||
"event_name",
|
||||
"start_date",
|
||||
"start_time",
|
||||
"end_date",
|
||||
"end_time",
|
||||
"coordinator_email",
|
||||
"event_link_name",
|
||||
]
|
||||
fields = [
|
||||
"event_name",
|
||||
"start_date",
|
||||
"start_time",
|
||||
"end_date",
|
||||
"end_time",
|
||||
"location_name",
|
||||
"coordinator_email",
|
||||
"event_link_name",
|
||||
"event_url",
|
||||
]
|
||||
|
||||
|
||||
class AddressModelAdmin(admin.ModelAdmin):
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
# Generated by Django 6.0.7 on 2026-08-04 17:59
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('schasite', '0012_alter_payments_date'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='calendarevent',
|
||||
name='end_time',
|
||||
field=models.TimeField(blank=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='calendarevent',
|
||||
name='start_time',
|
||||
field=models.TimeField(blank=True, null=True),
|
||||
),
|
||||
]
|
||||
@@ -66,6 +66,8 @@ class CalendarEvent(TimeInfoBase):
|
||||
event_name = models.CharField(max_length=256)
|
||||
start_date = models.DateField(blank=True, null=True)
|
||||
end_date = models.DateField(blank=True, null=True)
|
||||
start_time = models.TimeField(blank=True, null=True)
|
||||
end_time = models.TimeField(blank=True, null=True)
|
||||
location_name = models.CharField(max_length=256, blank=True, null=True)
|
||||
coordinator_email = models.EmailField(max_length=256, blank=True, null=True)
|
||||
event_link_name = models.CharField(max_length=64, blank=True, null=True)
|
||||
@@ -90,6 +92,19 @@ class CalendarEvent(TimeInfoBase):
|
||||
def no_date(self):
|
||||
return not self.has_date()
|
||||
|
||||
def time_range_display(self):
|
||||
"""Format start/end times for templates, e.g. '11:00 AM - 3:00 PM'."""
|
||||
from django.utils.formats import time_format
|
||||
|
||||
if not self.start_time and not self.end_time:
|
||||
return ""
|
||||
|
||||
start = time_format(self.start_time, "g:i A") if self.start_time else ""
|
||||
end = time_format(self.end_time, "g:i A") if self.end_time else ""
|
||||
if start and end:
|
||||
return f"{start} - {end}"
|
||||
return start or end
|
||||
|
||||
|
||||
class CalendarEventAddressModel(TimeInfoBase):
|
||||
calendar_event = models.OneToOneField(CalendarEvent, on_delete=models.CASCADE)
|
||||
|
||||
@@ -23,6 +23,9 @@
|
||||
{% else %}
|
||||
<p>Date: {{ event.start_date }} - {{ event.end_date }}</p>
|
||||
{% endif %}
|
||||
{% if event.time_range_display %}
|
||||
<p>Time: {{ event.time_range_display }}</p>
|
||||
{% endif %}
|
||||
<p>Location: {{ event.location_name }} - {{ event.calendareventaddressmodel }}</p>
|
||||
{% if event.coordinator_email %}
|
||||
<p>Coordinator: {{ event.coordinator_email }}</p>
|
||||
@@ -44,6 +47,9 @@
|
||||
{% else %}
|
||||
<p>Date: {{ event.start_date }} - {{ event.end_date }}</p>
|
||||
{% endif %}
|
||||
{% if event.time_range_display %}
|
||||
<p>Time: {{ event.time_range_display }}</p>
|
||||
{% endif %}
|
||||
<p>Location: {{ event.location_name }} - {{ event.calendareventaddressmodel }}</p>
|
||||
{% if event.coordinator_email %}
|
||||
<p>Coordinator: {{ event.coordinator_email }}</p>
|
||||
|
||||
@@ -115,7 +115,9 @@
|
||||
<div class="col-md-8">
|
||||
<div class="mb-3">
|
||||
<p class="mb-1"><i class="bi bi-calendar-event text-success me-2"></i><strong>Date:</strong> {{ event.start_date }}</p>
|
||||
<p class="mb-1"><i class="bi bi-clock text-success me-2"></i><strong>Time:</strong> 11:00 AM - 3:00 PM</p>
|
||||
{% if event.time_range_display %}
|
||||
<p class="mb-1"><i class="bi bi-clock text-success me-2"></i><strong>Time:</strong> {{ event.time_range_display }}</p>
|
||||
{% endif %}
|
||||
<p class="mb-1"><i class="bi bi-geo-alt text-success me-2"></i><strong>Location:</strong> {{ event.location_name }}</p>
|
||||
<p class="mb-1"><i class="bi bi-house text-success me-2"></i><strong>Address:</strong> </p>
|
||||
<p class="mb-1"><i class="bi bi-person text-success me-2"></i><strong>Coordinator:</strong> {{ event.coordinator_name }}</p>
|
||||
@@ -159,7 +161,9 @@
|
||||
<div class="col-md-8">
|
||||
<div class="mb-3">
|
||||
<p class="mb-1"><i class="bi bi-calendar-event text-secondary me-2"></i><strong>Date:</strong> {{ event.start_date }}</p>
|
||||
<p class="mb-1"><i class="bi bi-clock text-secondary me-2"></i><strong>Time:</strong> 9:00 AM - 12:00 PM</p>
|
||||
{% if event.time_range_display %}
|
||||
<p class="mb-1"><i class="bi bi-clock text-secondary me-2"></i><strong>Time:</strong> {{ event.time_range_display }}</p>
|
||||
{% endif %}
|
||||
<p class="mb-1"><i class="bi bi-geo-alt text-secondary me-2"></i><strong>Location:</strong> {{ event.location_name }}</p>
|
||||
<p class="mb-1"><i class="bi bi-house text-secondary me-2"></i><strong>Address:</strong> </p>
|
||||
<p class="mb-1"><i class="bi bi-person text-secondary me-2"></i><strong>Coordinator:</strong> {{ event.coordinator_name }}</p>
|
||||
|
||||
@@ -321,6 +321,23 @@ class CalendarEventTests(TestCase):
|
||||
self.assertFalse(undated.past_event())
|
||||
self.assertFalse(undated.future_event())
|
||||
|
||||
def test_time_range_display(self):
|
||||
event = CalendarEvent.objects.create(
|
||||
event_name="Timed Event",
|
||||
start_time=datetime.time(11, 0),
|
||||
end_time=datetime.time(15, 0),
|
||||
)
|
||||
self.assertEqual(event.time_range_display(), "11:00 AM - 3:00 PM")
|
||||
|
||||
start_only = CalendarEvent.objects.create(
|
||||
event_name="Start Only",
|
||||
start_time=datetime.time(9, 30),
|
||||
)
|
||||
self.assertEqual(start_only.time_range_display(), "9:30 AM")
|
||||
|
||||
no_time = CalendarEvent.objects.create(event_name="No Time")
|
||||
self.assertEqual(no_time.time_range_display(), "")
|
||||
|
||||
def test_calendar_page_splits_past_and_future(self):
|
||||
today = datetime.date.today()
|
||||
CalendarEvent.objects.create(
|
||||
|
||||
Reference in New Issue
Block a user