From c79d28738483479d7604ca5854fee3de33ffb161 Mon Sep 17 00:00:00 2001 From: Dana Lambert Date: Fri, 5 Nov 2021 14:22:07 +1300 Subject: [PATCH] Add habitat image endpoint, view and serializer --- .../api/migrations/0005_auto_20211104_2246.py | 29 ++++++++++ backend/right_tree/api/models.py | 12 ++-- backend/right_tree/api/serializers.py | 55 +++++++++++++------ backend/right_tree/api/views.py | 22 +++++++- backend/right_tree/urls.py | 1 + 5 files changed, 95 insertions(+), 24 deletions(-) create mode 100644 backend/right_tree/api/migrations/0005_auto_20211104_2246.py diff --git a/backend/right_tree/api/migrations/0005_auto_20211104_2246.py b/backend/right_tree/api/migrations/0005_auto_20211104_2246.py new file mode 100644 index 0000000..77fe6df --- /dev/null +++ b/backend/right_tree/api/migrations/0005_auto_20211104_2246.py @@ -0,0 +1,29 @@ +# Generated by Django 3.2.8 on 2021-11-04 22:46 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('api', '0004_alter_habitatimage_habitat'), + ] + + operations = [ + migrations.AlterField( + model_name='zone', + name='redirect_habitat', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='zone_redirects', to='api.habitatimage'), + ), + migrations.AlterField( + model_name='zoneimagesegment', + name='habitat_image', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='image_segments', to='api.habitatimage'), + ), + migrations.AlterField( + model_name='zoneimagesegment', + name='zone', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='image_segments', to='api.zone'), + ), + ] diff --git a/backend/right_tree/api/models.py b/backend/right_tree/api/models.py index 4129cc0..cbbcda0 100644 --- a/backend/right_tree/api/models.py +++ b/backend/right_tree/api/models.py @@ -52,6 +52,7 @@ class ToleranceLevel(models.Model): def __str__(self): return self.level + class Habitat(models.Model): name = models.CharField(max_length=50) @@ -74,7 +75,7 @@ class Zone(models.Model): variant = models.CharField(null=True, blank=True, max_length=50) refined_variant = models.CharField(null=True, blank=True, max_length=100) redirect_habitat = models.ForeignKey( - Habitat, blank=True, null=True, on_delete=models.CASCADE, related_name='redirect_habitat') + HabitatImage, blank=True, null=True, on_delete=models.CASCADE, related_name='zone_redirects') def __str__(self): refined_variant_str = f", {self.refined_variant}" if self.refined_variant is not None else "" @@ -84,15 +85,18 @@ class Zone(models.Model): class ZoneImageSegment(models.Model): zone = models.ForeignKey( - Zone, on_delete=models.CASCADE, related_name='zone') + Zone, on_delete=models.CASCADE, related_name='image_segments') habitat_image = models.ForeignKey( - HabitatImage, on_delete=models.CASCADE, related_name='habitat_image') + HabitatImage, on_delete=models.CASCADE, related_name='image_segments') segment_order = models.PositiveIntegerField(default=0) segment_percentage_width = models.PositiveIntegerField(default=0) def __str__(self): return f"{self.habitat_image.name}, {self.zone.name}" + class Meta: + ordering = ['segment_order', 'id'] + class Plant(models.Model): name = models.CharField(unique=True, max_length=50) @@ -117,4 +121,4 @@ class Plant(models.Model): zones = models.ManyToManyField(Zone) def __str__(self): - return self.name \ No newline at end of file + return self.name diff --git a/backend/right_tree/api/serializers.py b/backend/right_tree/api/serializers.py index 1d343cf..88e0fdd 100644 --- a/backend/right_tree/api/serializers.py +++ b/backend/right_tree/api/serializers.py @@ -2,23 +2,6 @@ from rest_framework import serializers from right_tree.api.models import * -class HabitatImageSerializer(serializers.HyperlinkedModelSerializer): - id = serializers.ReadOnlyField() - - class Meta: - model = HabitatImage - fields = ['id', 'name', 'image_filename'] - - -class HabitatSerializer(serializers.HyperlinkedModelSerializer): - id = serializers.ReadOnlyField() - images = HabitatImageSerializer(many=True) - - class Meta: - model = Habitat - fields = ['id', 'name', 'images'] - - class ToleranceLevelSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = ToleranceLevel @@ -57,9 +40,17 @@ class SoilVariantSerializer(serializers.HyperlinkedModelSerializer): fields = ['name'] +class SimpleHabitatImageSerializer(serializers.HyperlinkedModelSerializer): + id = serializers.ReadOnlyField() + + class Meta: + model = HabitatImage + fields = ['id', 'name', 'image_filename'] + + class ZoneSerializer(serializers.HyperlinkedModelSerializer): id = serializers.ReadOnlyField() - redirect_habitat = HabitatSerializer() + redirect_habitat = SimpleHabitatImageSerializer() class Meta: model = Zone @@ -67,6 +58,34 @@ class ZoneSerializer(serializers.HyperlinkedModelSerializer): 'refined_variant', 'redirect_habitat'] +class ZoneImageSegmentSerializer(serializers.HyperlinkedModelSerializer): + id = serializers.ReadOnlyField() + zone = ZoneSerializer() + + class Meta: + model = ZoneImageSegment + fields = ['id', 'zone', + 'segment_order', 'segment_percentage_width'] + + +class HabitatImageSerializer(serializers.HyperlinkedModelSerializer): + id = serializers.ReadOnlyField() + image_segments = ZoneImageSegmentSerializer(many=True) + + class Meta: + model = HabitatImage + fields = ['id', 'name', 'image_filename', 'image_segments'] + + +class HabitatSerializer(serializers.HyperlinkedModelSerializer): + id = serializers.ReadOnlyField() + images = HabitatImageSerializer(many=True) + + class Meta: + model = Habitat + fields = ['id', 'name', 'images'] + + class LocationDetailsSerializer(serializers.Serializer): ecologic_1 = serializers.CharField(max_length=50) ecologic_2 = serializers.CharField(max_length=50) diff --git a/backend/right_tree/api/views.py b/backend/right_tree/api/views.py index 3d9335f..8cad196 100644 --- a/backend/right_tree/api/views.py +++ b/backend/right_tree/api/views.py @@ -3,12 +3,13 @@ import json from django.contrib.gis.geos import Point from django.contrib.gis.db import models from django.http import HttpResponseBadRequest +from django.shortcuts import get_object_or_404 from rest_framework import viewsets from rest_framework.response import Response -from right_tree.api.models import Habitat, Plant, EcologicalDistrictLayer, SoilOrder -from right_tree.api.serializers import HabitatSerializer, PlantSerializer, SoilOrderSerializer, EcologicalDistrictLayerSerializer, AddressSerializer +from right_tree.api.models import Habitat, HabitatImage, Plant, EcologicalDistrictLayer, SoilOrder +from right_tree.api.serializers import HabitatImageSerializer, HabitatSerializer, PlantSerializer, SoilOrderSerializer, EcologicalDistrictLayerSerializer, AddressSerializer from .filters import * from .utils import get_address_from_coordinates @@ -85,3 +86,20 @@ class HabitatViewSet(viewsets.ModelViewSet): """ serializer_class = HabitatSerializer queryset = Habitat.objects.all() + + +class HabitatImageViewSet(viewsets.ViewSet): + """ + Viewset for a habitat image. + """ + + def list(self, request): + queryset = HabitatImage.objects.all() + serializer = HabitatImageSerializer(queryset, many=True) + return Response(serializer.data) + + def retrieve(self, request, pk=None): + queryset = HabitatImage.objects.all() + habitat_image = get_object_or_404(queryset, pk=pk) + serializer = HabitatImageSerializer(habitat_image) + return Response(serializer.data) diff --git a/backend/right_tree/urls.py b/backend/right_tree/urls.py index c8e5b4a..ebc0365 100644 --- a/backend/right_tree/urls.py +++ b/backend/right_tree/urls.py @@ -25,6 +25,7 @@ router.register(r'soil', views.SoilOrderViewSet, basename='soil') router.register(r'ecologicaldistrict', views.EcologicalDistrictViewSet, basename='ecologicaldistrict') router.register(r'address', views.LINZPropertyViewSet, basename='address') router.register(r'habitats', views.HabitatViewSet, basename='habitats') +router.register(r'habitatimage', views.HabitatImageViewSet,basename='habitatimage') urlpatterns = [ path('admin/', admin.site.urls),