feat: add is_featured/is_top_event fields and API endpoints

- Event model: added is_featured, is_top_event BooleanFields
- Migration 0007 applied to DB
- EventForm: checkboxes for both new fields
- EventAdmin: list_display, list_editable, list_filter for both flags
- FeaturedEventsAPI: POST /api/events/featured-events/ -> is_featured=True events
- TopEventsAPI: POST /api/events/top-events/ -> is_top_event=True events
This commit is contained in:
Ubuntu
2026-03-24 12:20:34 +00:00
parent b54439a4c2
commit aaaab190da
6 changed files with 88 additions and 7 deletions

View File

@@ -3,10 +3,11 @@ from .models import Event, EventImages
@admin.register(Event)
class EventAdmin(admin.ModelAdmin):
list_display = ('id','name','start_date','end_date','event_type','event_status')
list_filter = ('event_status','event_type')
search_fields = ('name','place','district')
list_display = ('id', 'name', 'start_date', 'end_date', 'event_type', 'event_status', 'is_featured', 'is_top_event')
list_filter = ('event_status', 'event_type', 'is_featured', 'is_top_event')
list_editable = ('is_featured', 'is_top_event')
search_fields = ('name', 'place', 'district')
@admin.register(EventImages)
class EventImagesAdmin(admin.ModelAdmin):
list_display = ('id','event','is_primary')
list_display = ('id', 'event', 'is_primary')

View File

@@ -1,7 +1,7 @@
from django import forms
from .models import Event
from .models import EventImages
from django_summernote.widgets import SummernoteWidget
class EventForm(forms.ModelForm):
class Meta:
@@ -11,7 +11,7 @@ class EventForm(forms.ModelForm):
'name': forms.TextInput(attrs={'class': 'form-control'}),
'description': forms.Textarea(attrs={'class': 'form-control'}),
'title': forms.TextInput(attrs={'class': 'form-control'}),
'important_information': forms.Textarea(attrs={'class': 'form-control'}),
'important_information': SummernoteWidget(attrs={'summernote': {'width': '100%', 'height': '400px'}}),
'venue_name': forms.TextInput(attrs={'class': 'form-control'}),
'start_date': forms.DateInput(attrs={'class': 'form-control', 'type': 'date', 'id': 'id_start_date'}),
'end_date': forms.DateInput(attrs={'class': 'form-control', 'type': 'date', 'id': 'id_end_date'}),
@@ -30,6 +30,8 @@ class EventForm(forms.ModelForm):
'cancelled_reason': forms.Textarea(attrs={'class': 'form-control'}),
'is_bookable': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
'is_eventify_event': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
'is_featured': forms.CheckboxInput(attrs={'class': 'form-check-input', 'id': 'id_is_featured'}),
'is_top_event': forms.CheckboxInput(attrs={'class': 'form-check-input', 'id': 'id_is_top_event'}),
}
def __init__(self, *args, **kwargs):

View File

@@ -0,0 +1,21 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('events', '0006_alter_event_source'),
]
operations = [
migrations.AddField(
model_name='event',
name='is_featured',
field=models.BooleanField(default=False, help_text='Show this event in the featured section'),
),
migrations.AddField(
model_name='event',
name='is_top_event',
field=models.BooleanField(default=False, help_text='Show this event in the Top Events section'),
),
]

View File

@@ -54,6 +54,9 @@ class Event(models.Model):
('community', 'Community'),
])
is_featured = models.BooleanField(default=False, help_text='Show this event in the featured section')
is_top_event = models.BooleanField(default=False, help_text='Show this event in the Top Events section')
def __str__(self):
return f"{self.name} ({self.start_date})"

View File

@@ -21,4 +21,6 @@ urlpatterns += [
path('events/events-by-category/', EventsByCategoryAPI.as_view(), name='api_events_by_category'),
path('events/events-by-month-year/', EventsByMonthYearAPI.as_view(), name='events_by_month_year'),
path('events/events-by-date/', EventsByDateAPI.as_view(), name='events_by_date'),
path('events/featured-events/', FeaturedEventsAPI.as_view(), name='featured_events'),
path('events/top-events/', TopEventsAPI.as_view(), name='top_events'),
]

View File

@@ -366,4 +366,56 @@ class EventsByDateAPI(APIView):
except Exception as e:
return JsonResponse(
{"status": "error", "message": str(e)},
)
)
@method_decorator(csrf_exempt, name='dispatch')
class FeaturedEventsAPI(APIView):
"""Returns events where is_featured=True — used for the homepage hero carousel."""
def post(self, request):
try:
user, token, data, error_response = validate_token_and_get_user(request)
if error_response:
return error_response
events = Event.objects.filter(is_featured=True).order_by('-created_date')
event_list = []
for e in events:
data_dict = model_to_dict(e)
try:
thumb = EventImages.objects.get(event=e.id, is_primary=True)
data_dict['thumb_img'] = request.build_absolute_uri(thumb.event_image.url)
except EventImages.DoesNotExist:
data_dict['thumb_img'] = ''
event_list.append(data_dict)
return JsonResponse({status: success, events: event_list})
except Exception as e:
return JsonResponse({status: error, message: str(e)})
@method_decorator(csrf_exempt, name='dispatch')
class TopEventsAPI(APIView):
"""Returns events where is_top_event=True — used for the Top Events section."""
def post(self, request):
try:
user, token, data, error_response = validate_token_and_get_user(request)
if error_response:
return error_response
events = Event.objects.filter(is_top_event=True).order_by('-created_date')
event_list = []
for e in events:
data_dict = model_to_dict(e)
try:
thumb = EventImages.objects.get(event=e.id, is_primary=True)
data_dict['thumb_img'] = request.build_absolute_uri(thumb.event_image.url)
except EventImages.DoesNotExist:
data_dict['thumb_img'] = ''
event_list.append(data_dict)
return JsonResponse({status: success, events: event_list})
except Exception as e:
return JsonResponse({status: error, message: str(e)})