feat: add source field with 3 options, fix EventListAPI fallback, add is_eventify_event to API response

- Event.source field updated: eventify, community, partner (radio select in form)
- EventListAPI: fallback to all events when pincode returns < 6
- EventListAPI: include is_eventify_event and source in serializer
- Admin API: add source to list serializer
- Django admin: source in list_display, list_filter, list_editable
- Event form template: proper radio button rendering for source field

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-30 11:23:03 +00:00
parent 388057b641
commit 43123d0ff1
19 changed files with 1381 additions and 38 deletions

View File

@@ -3,9 +3,9 @@ from .models import Event, EventImages
@admin.register(Event)
class EventAdmin(admin.ModelAdmin):
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')
list_display = ('id', 'name', 'start_date', 'end_date', 'event_type', 'event_status', 'source', 'is_featured', 'is_top_event')
list_filter = ('event_status', 'event_type', 'source', 'is_featured', 'is_top_event')
list_editable = ('is_featured', 'is_top_event', 'source')
search_fields = ('name', 'place', 'district')
@admin.register(EventImages)

View File

@@ -36,9 +36,13 @@ class EventForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Set source to 'official' only and hide the field
self.fields['source'].initial = 'official'
self.fields['source'].widget = forms.HiddenInput()
# Show source as visible radio buttons with Bootstrap styling
self.fields['source'].widget = forms.RadioSelect(
choices=self.fields['source'].choices,
attrs={'class': 'form-check-input'}
)
if not self.instance.pk:
self.fields['source'].initial = 'eventify'
# Check if all_year_event is True (from instance or initial data)
all_year_event = False
@@ -60,8 +64,7 @@ class EventForm(forms.ModelForm):
cleaned_data = super().clean()
all_year_event = cleaned_data.get('all_year_event', False)
# Force source to be 'official' only
cleaned_data['source'] = 'official'
# Source is now user-selectable (eventify/community/partner)
# If all_year_event is True, clear date/time fields
if all_year_event:

View File

@@ -0,0 +1,48 @@
# Generated by Django 4.2.21 on 2025-11-26 22:07
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
('master_data', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='Event',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created_date', models.DateField(auto_now_add=True)),
('name', models.CharField(max_length=200)),
('description', models.TextField()),
('start_date', models.DateField()),
('end_date', models.DateField()),
('latitude', models.DecimalField(decimal_places=6, max_digits=9)),
('longitude', models.DecimalField(decimal_places=6, max_digits=9)),
('pincode', models.CharField(max_length=10)),
('district', models.CharField(max_length=100)),
('state', models.CharField(max_length=100)),
('place', models.CharField(max_length=200)),
('is_bookable', models.BooleanField(default=False)),
('is_eventify_event', models.BooleanField(default=True)),
('outside_event_url', models.URLField(default='NA')),
('event_status', models.CharField(choices=[('created', 'Created'), ('cancelled', 'Cancelled'), ('pending', 'Pending'), ('completed', 'Completed'), ('postponed', 'Postponed')], default='pending', max_length=250)),
('cancelled_reason', models.TextField(default='NA')),
('event_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='master_data.eventtype')),
],
),
migrations.CreateModel(
name='EventImages',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('is_primary', models.BooleanField(default=False)),
('event_image', models.ImageField(upload_to='event_images')),
('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='events.event')),
],
),
]

View File

@@ -0,0 +1,28 @@
# Generated by Django 4.2.21 on 2025-11-28 20:56
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('events', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='event',
name='important_information',
field=models.TextField(blank=True),
),
migrations.AddField(
model_name='event',
name='title',
field=models.CharField(blank=True, max_length=250),
),
migrations.AddField(
model_name='event',
name='venue_name',
field=models.CharField(blank=True, max_length=250),
),
]

View File

@@ -0,0 +1,23 @@
# Generated by Django 4.2.21 on 2025-11-28 21:01
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('events', '0002_event_important_information_event_title_and_more'),
]
operations = [
migrations.AddField(
model_name='event',
name='end_time',
field=models.TimeField(blank=True, null=True),
),
migrations.AddField(
model_name='event',
name='start_time',
field=models.TimeField(blank=True, null=True),
),
]

View File

@@ -0,0 +1,28 @@
# Generated by Django 5.0 on 2025-12-19 22:14
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('events', '0003_event_end_time_event_start_time'),
]
operations = [
migrations.AddField(
model_name='event',
name='all_year_event',
field=models.BooleanField(default=False),
),
migrations.AlterField(
model_name='event',
name='end_date',
field=models.DateField(blank=True, null=True),
),
migrations.AlterField(
model_name='event',
name='start_date',
field=models.DateField(blank=True, null=True),
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 5.0 on 2025-12-19 22:31
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('events', '0004_event_all_year_event_alter_event_end_date_and_more'),
]
operations = [
migrations.AddField(
model_name='event',
name='source',
field=models.CharField(blank=True, choices=[('eventify', 'Eventify'), ('community', 'Community')], max_length=250),
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 5.0 on 2025-12-19 22:33
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('events', '0005_event_source'),
]
operations = [
migrations.AlterField(
model_name='event',
name='source',
field=models.CharField(blank=True, choices=[('official', 'Official'), ('community', 'Community')], max_length=250),
),
]

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

@@ -0,0 +1,33 @@
# Generated by Django 4.2.27 on 2026-03-13 16:55
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('events', '0006_alter_event_source'),
]
operations = [
migrations.AddField(
model_name='event',
name='gst_percentage_1',
field=models.IntegerField(default=0),
),
migrations.AddField(
model_name='event',
name='gst_percentage_2',
field=models.IntegerField(default=0),
),
migrations.AddField(
model_name='event',
name='include_gst',
field=models.BooleanField(default=False),
),
migrations.AlterField(
model_name='event',
name='event_status',
field=models.CharField(choices=[('created', 'Created'), ('cancelled', 'Cancelled'), ('pending', 'Pending'), ('completed', 'Completed'), ('postponed', 'Postponed'), ('published', 'Published'), ('live', 'Live'), ('flagged', 'Flagged')], default='pending', max_length=250),
),
]

View File

@@ -0,0 +1,25 @@
# Generated by Django 4.2.27 on 2026-03-14 15:57
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('partner', '0001_initial'),
('events', '0007_event_gst_percentage_1_event_gst_percentage_2_and_more'),
]
operations = [
migrations.AddField(
model_name='event',
name='is_partner_event',
field=models.BooleanField(default=False),
),
migrations.AddField(
model_name='event',
name='partner',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='partner.partner'),
),
]

View File

@@ -0,0 +1,23 @@
# Generated by Django 6.0.3 on 2026-03-14 19:34
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('events', '0008_event_is_partner_event_event_partner'),
]
operations = [
migrations.AlterField(
model_name='event',
name='id',
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
migrations.AlterField(
model_name='eventimages',
name='id',
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
]

View File

@@ -0,0 +1,14 @@
# Generated by Django 4.2.21 on 2026-03-24 14:43
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('events', '0007_add_is_featured_is_top_event'),
('events', '0009_alter_event_id_alter_eventimages_id'),
]
operations = [
]

View File

@@ -0,0 +1,43 @@
# Generated by Django 4.2.21 on 2026-03-30 10:30
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('events', '0010_merge_20260324_1443'),
]
operations = [
migrations.AlterField(
model_name='event',
name='created_date',
field=models.DateField(auto_now_add=True, db_index=True),
),
migrations.AlterField(
model_name='event',
name='event_status',
field=models.CharField(choices=[('created', 'Created'), ('cancelled', 'Cancelled'), ('pending', 'Pending'), ('completed', 'Completed'), ('postponed', 'Postponed'), ('published', 'Published'), ('live', 'Live'), ('flagged', 'Flagged')], db_index=True, default='pending', max_length=250),
),
migrations.AlterField(
model_name='event',
name='id',
field=models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
migrations.AlterField(
model_name='event',
name='source',
field=models.CharField(choices=[('eventify', 'Added by Eventify'), ('community', 'Community Contribution'), ('partner', 'Partner Event')], default='eventify', max_length=50),
),
migrations.AlterField(
model_name='event',
name='start_date',
field=models.DateField(blank=True, db_index=True, null=True),
),
migrations.AlterField(
model_name='eventimages',
name='id',
field=models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
]

View File

View File

@@ -49,9 +49,10 @@ class Event(models.Model):
important_information = models.TextField(blank=True)
venue_name = models.CharField(max_length=250, blank=True)
source = models.CharField(max_length=250, blank=True, choices=[
('official', 'Official'),
('community', 'Community'),
source = models.CharField(max_length=50, default='eventify', choices=[
('eventify', 'Added by Eventify'),
('community', 'Community Contribution'),
('partner', 'Partner Event'),
])
is_featured = models.BooleanField(default=False, help_text='Show this event in the featured section')