diff --git a/api/serializers/category.py b/api/serializers/category.py index 10e10c5..92d63de 100644 --- a/api/serializers/category.py +++ b/api/serializers/category.py @@ -3,8 +3,6 @@ from web.models.category import Category class CategorySerializer(serializers.ModelSerializer): - # to_representation(self, instance) if needed - # fk = Serializer() class Meta: model = Category diff --git a/api/serializers/event.py b/api/serializers/event.py index 17e34f5..ada01b0 100644 --- a/api/serializers/event.py +++ b/api/serializers/event.py @@ -1,12 +1,41 @@ from rest_framework import serializers +from django.forms.models import model_to_dict from web.models.event import Event +from web.models.event_category import EventCategory +from web.models.event_tag import EventTag class EventSerializer(serializers.ModelSerializer): - # to_representation(self, instance) if needed - # fk = Serializer() class Meta: model = Event fields = '__all__' + def to_representation(self, instance): + representation = super().to_representation(instance) + + event_categories = EventCategory.objects.filter(event=instance).filter(active=True).all() + event_tags = EventTag.objects.filter(event=instance).filter(active=True).all() + + categories = [] + if event_categories.exists(): + for event_category in event_categories: + categories.append({ + 'id': event_category.category.id, + 'name': event_category.category.name, + 'description': event_category.category.description, + '_meta': model_to_dict(event_category) + }) + + tags = [] + if event_tags.exists(): + for event_tag in event_tags: + tags.append({ + 'id': event_tag.tag.id, + 'name': event_tag.tag.name, + '_meta': model_to_dict(event_tag) + }) + + representation['categories'] = categories + representation['tags'] = tags + return representation diff --git a/api/serializers/event_category.py b/api/serializers/event_category.py new file mode 100644 index 0000000..dc37d11 --- /dev/null +++ b/api/serializers/event_category.py @@ -0,0 +1,10 @@ +from rest_framework import serializers + +from web.models.event_category import EventCategory + + +class EventCategorySerializer(serializers.ModelSerializer): + + class Meta: + model = EventCategory + fields = "all" diff --git a/api/serializers/event_tag.py b/api/serializers/event_tag.py new file mode 100644 index 0000000..779c5af --- /dev/null +++ b/api/serializers/event_tag.py @@ -0,0 +1,10 @@ +from rest_framework import serializers + +from web.models.event_tag import EventTag + + +class EventTagSerializer(serializers.ModelSerializer): + + class Meta: + model = EventTag + fields = "all" diff --git a/api/views/base.py b/api/views/base.py index ceeeba3..909d64c 100644 --- a/api/views/base.py +++ b/api/views/base.py @@ -15,7 +15,7 @@ class BaseView(APIView): def _build_multi_response(self, data): serialized_data = [] for d in data: - serializer = self.SERIALIZER(data) + serializer = self.SERIALIZER(d) serialized_data.append(serializer.data) response = Response() diff --git a/api/views/event.py b/api/views/event.py index 58143fb..64ebb35 100644 --- a/api/views/event.py +++ b/api/views/event.py @@ -1,19 +1,25 @@ import json +from django.db import transaction from django.shortcuts import get_object_or_404 from api.serializers.event import EventSerializer from api.views.base import BaseView +from web.models.category import Category +from web.models.event_category import EventCategory from web.models.event import Event +from web.models.tag import Tag +from web.models.event_tag import EventTag class EventView(BaseView): SERIALIZER = EventSerializer def get(self, request, event_id): - event = get_object_or_404(Event, pk=event_id) + event = get_object_or_404(Event, pk=event_id, active=True) return self._build_response(event) + @transaction.atomic def post(self, request): data = json.loads(request.body) event = Event( @@ -32,8 +38,41 @@ class EventView(BaseView): ) event.save() + + categories = data.get('categories', []) + self._create_event_categories(categories, event) + + tag_names = data.get('tags', []) + self._create_event_tags(tag_names, event) + return self._build_response(event) + def _create_event_categories(self, categories, event): + event_categories = [] + for category_id in categories: + category = get_object_or_404(Category, pk=category_id) + event_category = EventCategory( + event=event, + category=category + ) + + event_categories.append(event_category) + EventCategory.objects.bulk_create(event_categories) + + def _create_event_tags(self, tag_names, event): + event_tags = [] + for tag_name in tag_names: + tag, created = Tag.objects.get_or_create(name=tag_name) + + event_tag = EventTag( + tag=tag, + event=event + ) + + event_tags.append(event_tag) + EventTag.objects.bulk_create(event_tags) + + @transaction.atomic def put(self, request, event_id): data = json.loads(request.body) @@ -52,9 +91,64 @@ class EventView(BaseView): event.email = data.get('email', event.email) event.phone_number = data.get('phone_number', event.phone_number) + categories = data.get('categories', []) + self._update_event_categories(categories, event) + + tag_names = data.get('tags', []) + self._update_event_tags(tag_names, event) + event.save() self._build_response(event) + def _update_event_categories(self, categories, event): + if categories: + current_event_categories = EventCategory.objects.filter(event=event).filter(active=True).all() + current_event_category_map = {ec.category.id: ec for ec in current_event_categories} + + for current_event_category in current_event_categories: + if current_event_category.category.id not in categories: + current_event_category.active = False + current_event_category.save() + + new_event_categories = [] + for category_id in categories: + category = get_object_or_404(Category, pk=category_id) + if category not in current_event_category_map: + event_category = EventCategory( + category=category, + event=event + ) + + new_event_categories.append(event_category) + + if new_event_categories: + EventCategory.objects.bulk_create(new_event_categories) + + def _update_event_tags(self, tag_names, event): + if tag_names: + current_event_tags = EventTag.objects.filter(event=event).filter(active=True).all() + current_event_tag_names = [x.name for x in current_event_tags] + + for current_event_tag in current_event_tags: + if current_event_tag.tag.name not in tag_names: + current_event_tag.active = False + current_event_tag.save() + + new_event_tags = [] + for tag_name in tag_names: + if tag_name not in current_event_tag_names: + tag, created = Tag.objects.get_or_create(name=tag_name) + + event_tag = EventTag( + tag=tag, + event=event + ) + + new_event_tags.append(event_tag) + + if new_event_tags: + EventTag.objects.bulk_create(new_event_tags) + def delete(self, request, event_id): event = get_object_or_404(Event, pk=event_id) event.active = False diff --git a/test_requests/event_post.py b/test_requests/event_post.py index 88fe122..21e5b21 100644 --- a/test_requests/event_post.py +++ b/test_requests/event_post.py @@ -3,7 +3,7 @@ import requests url = "http://127.0.0.1:8000/api/event" data = { - "name": "Test Event 2", + "name": "Test Event 3", "description": "this is a test", "url": "https://www.domdit.com", "address": "31 Fleetwood Dr Hazlet Nj", @@ -14,8 +14,11 @@ data = { "end_time": "2026-08-14T01:34:38Z", "rain_date": "2026-06-15T01:34:42Z", "email": "me@domdit.com", - "phone_number": "" + "phone_number": "", + "categories": [1], + "tags": ["tag1", "tag2", "tag4"] + } -resp = requests.post(url, data=data) +resp = requests.post(url, json=data) print(resp.status_code) diff --git a/web/migrations/0002_alter_eventcategory_category.py b/web/migrations/0002_alter_eventcategory_category.py new file mode 100644 index 0000000..9b58ab0 --- /dev/null +++ b/web/migrations/0002_alter_eventcategory_category.py @@ -0,0 +1,23 @@ +# Generated by Django 6.0.6 on 2026-06-21 00:12 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("web", "0001_initial"), + ] + + operations = [ + migrations.AlterField( + model_name="eventcategory", + name="category", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="category", + to="web.category", + ), + ), + ] diff --git a/web/models/event_category.py b/web/models/event_category.py index 04c9522..411682e 100644 --- a/web/models/event_category.py +++ b/web/models/event_category.py @@ -7,7 +7,7 @@ from web.models.category import Category class EventCategory(BaseModel): event = models.ForeignKey(Event, on_delete=models.CASCADE) - category = models.ForeignKey(Category, on_delete=models.CASCADE) + category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name="category") class Meta: db_table = 'event_categories'