From bf4e3556e3ab90480f4f0276c5b7c2ed17a5e182 Mon Sep 17 00:00:00 2001 From: Sam McAlilly Date: Thu, 2 Nov 2023 14:50:54 -0500 Subject: [PATCH 1/5] add doc about serializing with drf outside of drf --- django/serializing-data.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 django/serializing-data.md diff --git a/django/serializing-data.md b/django/serializing-data.md new file mode 100644 index 0000000..e422211 --- /dev/null +++ b/django/serializing-data.md @@ -0,0 +1,14 @@ +# Using Django Rest Framework serializers for data serialization +Django Rest Framework can be useful for serializing data beyond the context of an API endpoint. We find it helpful whenever we're serializing json for use in a React component, like when you need to pass GeoJSON to a map or your data objects have nested relationships. + +DRF's docs are the best place to learn about the serializer classes, but this document points you to see how we use this pattern within the DataMade stack. + +## Use cases +- Serializing GeoJSON or JSON data for use in a Django template or React component that's [baked into the Django template](/django/django-react-integration.md) +- Serializing a queryset with nested relationships + - This helps with database efficiency because you can leverage `prefetch_related` and then serialize all of the related data in a cleaner way. [This blog post is a good resource to learn about that](https://hakibenita.com/django-rest-framework-slow). + + +## DataMade Examples: +1. **IL NWSS app**: We [serialized GeoJSON data and linked the data is linked to model](https://github.com/illinoisdpi/il-nwss-dashboard/pull/171). +2. **CCFP Asset Dashboard**: We had to [serialize GeoJSON with a readable and writeable API endpoint](https://github.com/fpdcc/ccfp-asset-dashboard/pull/106). Reading and writing with the GeoJSON serializers wasn't straightforward so this example might help somebody who needs to do that. From 7cfd1fec2c629f14417e5c42e7ec56c35be549ef Mon Sep 17 00:00:00 2001 From: Sam McAlilly Date: Thu, 2 Nov 2023 15:59:53 -0500 Subject: [PATCH 2/5] add link to drf docs --- django/serializing-data.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/django/serializing-data.md b/django/serializing-data.md index e422211..b98912e 100644 --- a/django/serializing-data.md +++ b/django/serializing-data.md @@ -1,7 +1,7 @@ # Using Django Rest Framework serializers for data serialization Django Rest Framework can be useful for serializing data beyond the context of an API endpoint. We find it helpful whenever we're serializing json for use in a React component, like when you need to pass GeoJSON to a map or your data objects have nested relationships. -DRF's docs are the best place to learn about the serializer classes, but this document points you to see how we use this pattern within the DataMade stack. +[DRF's docs](https://www.django-rest-framework.org/api-guide/serializers/) are the best place to learn about the serializer classes, but this document has examples for how we use this pattern within the DataMade stack. ## Use cases - Serializing GeoJSON or JSON data for use in a Django template or React component that's [baked into the Django template](/django/django-react-integration.md) From 0875a368d06ff3e71963ff701528e6807758c882 Mon Sep 17 00:00:00 2001 From: Sam McAlilly Date: Fri, 12 Apr 2024 10:50:56 -0400 Subject: [PATCH 3/5] show the code instead of linking to it --- django/serializing-data.md | 67 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 3 deletions(-) diff --git a/django/serializing-data.md b/django/serializing-data.md index b98912e..f489466 100644 --- a/django/serializing-data.md +++ b/django/serializing-data.md @@ -9,6 +9,67 @@ Django Rest Framework can be useful for serializing data beyond the context of a - This helps with database efficiency because you can leverage `prefetch_related` and then serialize all of the related data in a cleaner way. [This blog post is a good resource to learn about that](https://hakibenita.com/django-rest-framework-slow). -## DataMade Examples: -1. **IL NWSS app**: We [serialized GeoJSON data and linked the data is linked to model](https://github.com/illinoisdpi/il-nwss-dashboard/pull/171). -2. **CCFP Asset Dashboard**: We had to [serialize GeoJSON with a readable and writeable API endpoint](https://github.com/fpdcc/ccfp-asset-dashboard/pull/106). Reading and writing with the GeoJSON serializers wasn't straightforward so this example might help somebody who needs to do that. +## Examples: +In the IL NWSS project, we serialized GeoJSON data and linked needed data that is related to the model. I can't share the private repo link since not everybody has access, so these are the relevant changes we made: + +### models.py +```python +from django.contrib.gis.db import models' + + +class SewershedArea(models.Model): + """Simplified version of the geo model""" + treatment_plant = ParentalKey( + WastewaterTreatmentPlant, + related_name='sewershed_area', + on_delete=models.CASCADE, + primary_key=True, + ) + boundary = models.GeometryField(blank=True, null=True, srid=3435, dim=2) + +``` + +### serializers.py +```python +from rest_framework_gis.serializers import ( + GeoFeatureModelSerializer, + GeometrySerializerMethodField, +) + + +class SewershedAreaGeoSerializer(GeoFeatureModelSerializer): + class Meta: + model = SewershedArea + fields = ('pk', 'boundary', 'plant_name', 'plant_url', 'plant_city', 'site_id') + geo_field = 'boundary' + + boundary = GeometrySerializerMethodField() + + plant_name = serializers.SerializerMethodField() + plant_url = serializers.SerializerMethodField() + plant_city = serializers.SerializerMethodField() + site_id = serializers.SerializerMethodField() + + def get_boundary(self, obj): + return obj.boundary.transform(4326, clone=True) + + def get_plant_name(self, obj): + return obj.treatment_plant.name + + def get_plant_url(self, obj): + return obj.treatment_plant.get_absolute_url() + + def get_plant_city(self, obj): + return obj.treatment_plant.city + + def get_site_id(self, obj): + return obj.treatment_plant.site_id + + +``` + +### Use the data +You can use the serialized data in at least two ways: +1. Serialize the GeoJSON data in your view and pass it into the context, so that you can access that data within the template and pass it into your React component as props (as described in [this how-to documentation](/django/django-react-integration.md#set-react-props-and-root-element-on-the-window-object)) + +2. Setup an API endpoint with Django Rest Framework From 7f458ad0aca968f3395ec64bcd1afd7db0bf0f8f Mon Sep 17 00:00:00 2001 From: Sam McAlilly Date: Fri, 12 Apr 2024 11:40:03 -0400 Subject: [PATCH 4/5] edits --- django/serializing-data.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/django/serializing-data.md b/django/serializing-data.md index f489466..4d2ab88 100644 --- a/django/serializing-data.md +++ b/django/serializing-data.md @@ -1,7 +1,7 @@ # Using Django Rest Framework serializers for data serialization Django Rest Framework can be useful for serializing data beyond the context of an API endpoint. We find it helpful whenever we're serializing json for use in a React component, like when you need to pass GeoJSON to a map or your data objects have nested relationships. -[DRF's docs](https://www.django-rest-framework.org/api-guide/serializers/) are the best place to learn about the serializer classes, but this document has examples for how we use this pattern within the DataMade stack. +[Django Rest Framework's documentation](https://www.django-rest-framework.org/api-guide/serializers/) is the best place to learn about the serializer classes, but this document shows how we use this pattern within the DataMade stack. ## Use cases - Serializing GeoJSON or JSON data for use in a Django template or React component that's [baked into the Django template](/django/django-react-integration.md) @@ -26,7 +26,6 @@ class SewershedArea(models.Model): primary_key=True, ) boundary = models.GeometryField(blank=True, null=True, srid=3435, dim=2) - ``` ### serializers.py @@ -64,8 +63,6 @@ class SewershedAreaGeoSerializer(GeoFeatureModelSerializer): def get_site_id(self, obj): return obj.treatment_plant.site_id - - ``` ### Use the data From 5514928de8342f94c878f3f4ae63b6f0d39d67ab Mon Sep 17 00:00:00 2001 From: Sam McAlilly Date: Fri, 12 Apr 2024 15:37:03 -0400 Subject: [PATCH 5/5] add link on home --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 5f04d3d..a5cc4f7 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ _In alphabetical order and including links to external repository-based document - [Forms](django/forms.md) - [Translation](django/translation.md) - [Wagtail](django/wagtail/) + - [Serializing GeoJSON data](django/serializing-data.md) - [Docker](docker/) - [Docker for local development](docker/local-development.md) - [Templates for containerizing your application](docker/templates/)