From 671c6ec6f5e3be3d3a07b6c705ab04112d696e9a Mon Sep 17 00:00:00 2001 From: moanos Date: Tue, 17 Jun 2025 22:43:14 +0200 Subject: [PATCH] feat: Add rescue orgs as geojson via API --- src/fellchensammlung/api/renderers.py | 2 +- src/fellchensammlung/api/serializers.py | 32 +++++++++++++++++++++++++ src/fellchensammlung/api/urls.py | 3 ++- src/fellchensammlung/api/views.py | 8 ++++++- 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/fellchensammlung/api/renderers.py b/src/fellchensammlung/api/renderers.py index 255dbc0..fb0255d 100644 --- a/src/fellchensammlung/api/renderers.py +++ b/src/fellchensammlung/api/renderers.py @@ -21,7 +21,7 @@ class GeoJSONRenderer(BaseRenderer): "properties": { k: v for k, v in item.items() }, - "id": f"adoptionnotice/{item['id']}" + "id": f"{item['id']}" } features.append(feature) diff --git a/src/fellchensammlung/api/serializers.py b/src/fellchensammlung/api/serializers.py index 6c83eb9..93d3a1d 100644 --- a/src/fellchensammlung/api/serializers.py +++ b/src/fellchensammlung/api/serializers.py @@ -83,6 +83,38 @@ class AdoptionNoticeGeoJSONSerializer(serializers.ModelSerializer): return f"{obj.location.city}" return None +class RescueOrgeGeoJSONSerializer(serializers.ModelSerializer): + name = serializers.CharField() + url = serializers.SerializerMethodField() + location_hr = serializers.SerializerMethodField() + coordinates = serializers.SerializerMethodField() + + class Meta: + model = AdoptionNotice + fields = ('id', 'name', 'description', 'url', 'location_hr', 'coordinates') + + def get_url(self, obj): + return obj.get_absolute_url() + + def get_coordinates(self, obj): + """ + Coordinates are randomly moved around real location, roughly in a circle. The object id is used as angle so that + points are always displayed at the same location (as if they were a seed for a random function). + + It's not exactly a circle, because the earth is round. + """ + if obj.location: + return [obj.location.longitude, obj.location.latitude] + return None + + def get_location_hr(self, obj): + if obj.location.city: + return f"{obj.location.city}" + elif obj.location: + return f"{obj.location}" + return None + + class AnimalCreateSerializer(serializers.ModelSerializer): class Meta: diff --git a/src/fellchensammlung/api/urls.py b/src/fellchensammlung/api/urls.py index 953dadc..508eee8 100644 --- a/src/fellchensammlung/api/urls.py +++ b/src/fellchensammlung/api/urls.py @@ -2,7 +2,7 @@ from django.urls import path from .views import ( AdoptionNoticeApiView, AnimalApiView, RescueOrganizationApiView, AddImageApiView, SpeciesApiView, LocationApiView, - AdoptionNoticeGeoJSONView + AdoptionNoticeGeoJSONView, RescueOrgGeoJSONView ) urlpatterns = [ @@ -12,6 +12,7 @@ urlpatterns = [ path("animals/", AnimalApiView.as_view(), name="api-animal-list"), path("animals//", AnimalApiView.as_view(), name="api-animal-detail"), path("organizations/", RescueOrganizationApiView.as_view(), name="api-organization-list"), + path("organizations.geojson", RescueOrgGeoJSONView.as_view(), name="api-organization-list-geojson"), path("organizations//", RescueOrganizationApiView.as_view(), name="api-organization-detail"), path("images/", AddImageApiView.as_view(), name="api-add-image"), path("species/", SpeciesApiView.as_view(), name="api-species-list"), diff --git a/src/fellchensammlung/api/views.py b/src/fellchensammlung/api/views.py index 4d442a4..40e00ca 100644 --- a/src/fellchensammlung/api/views.py +++ b/src/fellchensammlung/api/views.py @@ -14,7 +14,7 @@ from .renderers import GeoJSONRenderer from .serializers import ( AnimalGetSerializer, AnimalCreateSerializer, - RescueOrganizationSerializer, + RescueOrgeGeoJSONSerializer, AdoptionNoticeSerializer, ImageCreateSerializer, SpeciesSerializer, RescueOrganizationSerializer, @@ -364,3 +364,9 @@ class AdoptionNoticeGeoJSONView(ListAPIView): adoptionnoticestatus__major_status=AdoptionNoticeStatus.ACTIVE) serializer_class = AdoptionNoticeGeoJSONSerializer renderer_classes = [GeoJSONRenderer] + + +class RescueOrgGeoJSONView(ListAPIView): + queryset = RescueOrganization.objects.select_related('location').filter(location__isnull=False) + serializer_class = RescueOrgeGeoJSONSerializer + renderer_classes = [GeoJSONRenderer]