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:
@@ -3,10 +3,11 @@ from .models import Event, EventImages
|
|||||||
|
|
||||||
@admin.register(Event)
|
@admin.register(Event)
|
||||||
class EventAdmin(admin.ModelAdmin):
|
class EventAdmin(admin.ModelAdmin):
|
||||||
list_display = ('id','name','start_date','end_date','event_type','event_status')
|
list_display = ('id', 'name', 'start_date', 'end_date', 'event_type', 'event_status', 'is_featured', 'is_top_event')
|
||||||
list_filter = ('event_status','event_type')
|
list_filter = ('event_status', 'event_type', 'is_featured', 'is_top_event')
|
||||||
search_fields = ('name','place','district')
|
list_editable = ('is_featured', 'is_top_event')
|
||||||
|
search_fields = ('name', 'place', 'district')
|
||||||
|
|
||||||
@admin.register(EventImages)
|
@admin.register(EventImages)
|
||||||
class EventImagesAdmin(admin.ModelAdmin):
|
class EventImagesAdmin(admin.ModelAdmin):
|
||||||
list_display = ('id','event','is_primary')
|
list_display = ('id', 'event', 'is_primary')
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
from django import forms
|
from django import forms
|
||||||
from .models import Event
|
from .models import Event
|
||||||
from .models import EventImages
|
from .models import EventImages
|
||||||
|
from django_summernote.widgets import SummernoteWidget
|
||||||
|
|
||||||
class EventForm(forms.ModelForm):
|
class EventForm(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
@@ -11,7 +11,7 @@ class EventForm(forms.ModelForm):
|
|||||||
'name': forms.TextInput(attrs={'class': 'form-control'}),
|
'name': forms.TextInput(attrs={'class': 'form-control'}),
|
||||||
'description': forms.Textarea(attrs={'class': 'form-control'}),
|
'description': forms.Textarea(attrs={'class': 'form-control'}),
|
||||||
'title': forms.TextInput(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'}),
|
'venue_name': forms.TextInput(attrs={'class': 'form-control'}),
|
||||||
'start_date': forms.DateInput(attrs={'class': 'form-control', 'type': 'date', 'id': 'id_start_date'}),
|
'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'}),
|
'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'}),
|
'cancelled_reason': forms.Textarea(attrs={'class': 'form-control'}),
|
||||||
'is_bookable': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
|
'is_bookable': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
|
||||||
'is_eventify_event': 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):
|
def __init__(self, *args, **kwargs):
|
||||||
|
|||||||
21
events/migrations/0007_add_is_featured_is_top_event.py
Normal file
21
events/migrations/0007_add_is_featured_is_top_event.py
Normal 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'),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -54,6 +54,9 @@ class Event(models.Model):
|
|||||||
('community', 'Community'),
|
('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):
|
def __str__(self):
|
||||||
return f"{self.name} ({self.start_date})"
|
return f"{self.name} ({self.start_date})"
|
||||||
|
|
||||||
|
|||||||
@@ -21,4 +21,6 @@ urlpatterns += [
|
|||||||
path('events/events-by-category/', EventsByCategoryAPI.as_view(), name='api_events_by_category'),
|
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-month-year/', EventsByMonthYearAPI.as_view(), name='events_by_month_year'),
|
||||||
path('events/events-by-date/', EventsByDateAPI.as_view(), name='events_by_date'),
|
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'),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -366,4 +366,56 @@ class EventsByDateAPI(APIView):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
return JsonResponse(
|
return JsonResponse(
|
||||||
{"status": "error", "message": str(e)},
|
{"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)})
|
||||||
|
|||||||
Reference in New Issue
Block a user