put and post coords

This commit is contained in:
Dominic DiTaranto 2026-06-21 16:57:02 -04:00
parent 92db8d61ed
commit 058a64b4a9
5 changed files with 73 additions and 8 deletions

View file

@ -16,7 +16,16 @@ class EventSerializer(serializers.ModelSerializer):
event_categories = EventCategory.objects.filter(event=instance).filter(active=True).all()
event_tags = EventTag.objects.filter(event=instance).filter(active=True).all()
representation['location'] = {
'lng': instance.coordinates.x if instance.coordinates else None,
'lat': instance.coordinates.y if instance.coordinates else None
}
representation['categories'] = self._parse_categories(event_categories)
representation['tags'] = self._parse_tags(event_tags)
return representation
def _parse_categories(self, event_categories):
categories = []
if event_categories.exists():
for event_category in event_categories:
@ -26,7 +35,9 @@ class EventSerializer(serializers.ModelSerializer):
'description': event_category.category.description,
'_meta': model_to_dict(event_category)
})
return categories
def _parse_tags(self, event_tags):
tags = []
if event_tags.exists():
for event_tag in event_tags:
@ -35,7 +46,4 @@ class EventSerializer(serializers.ModelSerializer):
'name': event_tag.tag.name,
'_meta': model_to_dict(event_tag)
})
representation['categories'] = categories
representation['tags'] = tags
return representation
return tags

View file

@ -21,3 +21,9 @@ class BaseView(APIView):
response = Response()
response.data = serialized_data
return response
def error_response(self, status_code, description):
response = Response()
response.status_code = status_code
response.data = {"error": description}
return response

View file

@ -1,5 +1,7 @@
import json
from django.contrib.gis.geos import Point
from django.contrib.gis.measure import D
from django.db import transaction
from django.shortcuts import get_object_or_404
@ -15,13 +17,35 @@ from web.models.event_tag import EventTag
class EventView(BaseView):
SERIALIZER = EventSerializer
def get(self, request, event_id):
def get(self, request, event_id=None):
if event_id:
event = get_object_or_404(Event, pk=event_id, active=True)
return self._build_response(event)
else:
return self._get_events_by_radius(request)
def _get_events_by_radius(self, request):
lat = request.GET.get('lat')
lng = request.GET.get('lng')
r = request.GET.get('r')
if all([lat, lng, r]):
try:
user_location = Point(float(lng), float(lat), srid=4326)
events = Event.objects.filter(active=True).filter(coordinates__dwithin=(user_location, D(mi=float(r)))).all()
return self._build_multi_response(events)
except ValueError:
return self.error_response(400, 'Invalid coordinates or radius format')
else:
return self.error_response(400, 'Must include lat, lng, and r in query string')
@transaction.atomic
def post(self, request):
data = json.loads(request.body)
location = data.get('location', {})
coordinates = Point(location.get("lng"), location.get("lat"), srid=4326)
event = Event(
name=data.get('name'),
description=data.get('description'),
@ -35,6 +59,7 @@ class EventView(BaseView):
rain_date=data.get('rain_date'),
email=data.get('email'),
phone_number=data.get('phone_number'),
coordinates=coordinates,
)
event.save()
@ -78,6 +103,11 @@ class EventView(BaseView):
event = get_object_or_404(Event, pk=event_id)
location = data.get('location', {})
if location:
coordinates = Point(location.get("lng"), location.get("lat"), srid=4326)
event.coordinates = coordinates
event.name = data.get('name', event.name)
event.description = data.get('description', event.description)
event.url = data.get('url', event.url)

View file

@ -0,0 +1,21 @@
# Generated by Django 6.0.6 on 2026-06-21 19:33
import django.contrib.gis.db.models.fields
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("web", "0003_event_coordinates"),
]
operations = [
migrations.AlterField(
model_name="event",
name="coordinates",
field=django.contrib.gis.db.models.fields.PointField(
blank=True, default=None, geography=True, null=True, srid=4326
),
),
]

View file

@ -14,7 +14,7 @@ class Event(BaseModel):
description = models.TextField()
url = models.URLField()
address = models.CharField()
coordinates = models.PointField(blank=True, default=None, null=True)
coordinates = models.PointField(blank=True, default=None, null=True, srid=4326, geography=True)
status = models.CharField(max_length=20, choices=Status.choices, default=Status.SCHEDULED)
price = models.DecimalField(max_digits=10, default=None, blank=True, decimal_places=2)
require_rsvp = models.BooleanField()