From 717271855112736e9d28ce198e8ec5436d76e884 Mon Sep 17 00:00:00 2001 From: Jose Tomas Robles Hahn Date: Wed, 17 Jul 2024 18:28:03 -0400 Subject: [PATCH] feat: Add mapping of Django model fields to DRF serializer fields MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use it to extend DRF serializers that inherit from `ModelSerializer` so that Django model fields from `cl_sii.extras.dj_model_fields` do not have to be explicitly defined in the serializer. The source code originates from an internal application (see commit 3bea7182 of that application’s source code), and was originally written by Jose Tomas Robles Hahn. --- src/cl_sii/extras/drf_serializers.py | 42 ++++++++++++++++++++++++ src/tests/test_extras_drf_serializers.py | 24 ++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 src/cl_sii/extras/drf_serializers.py create mode 100644 src/tests/test_extras_drf_serializers.py diff --git a/src/cl_sii/extras/drf_serializers.py b/src/cl_sii/extras/drf_serializers.py new file mode 100644 index 00000000..3473d02b --- /dev/null +++ b/src/cl_sii/extras/drf_serializers.py @@ -0,0 +1,42 @@ +from __future__ import annotations + + +try: + import rest_framework +except ImportError as exc: # pragma: no cover + raise ImportError("Package 'djangorestframework' is required to use this module.") from exc +try: + import django +except ImportError as exc: # pragma: no cover + raise ImportError("Package 'Django' is required to use this module.") from exc + +from typing import Mapping, Type + +import django.db.models +import rest_framework.serializers + +import cl_sii.extras.dj_model_fields +import cl_sii.extras.drf_fields + + +model_serializer_field_mapping: Mapping[ + Type[django.db.models.Field], Type[rest_framework.serializers.Field] +] +""" +Mapping of Django model fields to DRF serializer fields. + +Use this to extend DRF serializers that inherit from :class:`ModelSerializer` so +that Django model fields from :mod:`cl_sii.extras.dj_model_fields` do not have +to be explicitly defined in the serializer. + +Usage example: + +>>> class ExampleSerializer(rest_framework.serializers.ModelSerializer): +... serializer_field_mapping = { +... **rest_framework.serializers.ModelSerializer.serializer_field_mapping, +... **model_serializer_field_mapping, +... } +""" +model_serializer_field_mapping = { + cl_sii.extras.dj_model_fields.RutField: cl_sii.extras.drf_fields.RutField, +} diff --git a/src/tests/test_extras_drf_serializers.py b/src/tests/test_extras_drf_serializers.py new file mode 100644 index 00000000..2a26aeb1 --- /dev/null +++ b/src/tests/test_extras_drf_serializers.py @@ -0,0 +1,24 @@ +from __future__ import annotations + +import unittest + +import django.db.models +import rest_framework.serializers + +import cl_sii.extras.drf_serializers + + +class ModelSerializerFieldMappingTestCase(unittest.TestCase): + """ + Tests for :attr:`model_serializer_field_mapping`. + """ + + def test_types(self) -> None: + serializer_field_mapping = { + **rest_framework.serializers.ModelSerializer.serializer_field_mapping, + **cl_sii.extras.drf_serializers.model_serializer_field_mapping, + } + + for k, v in serializer_field_mapping.items(): + self.assertTrue(issubclass(k, django.db.models.Field)) + self.assertTrue(issubclass(v, rest_framework.serializers.Field))