From 88d5b97ca1b3a4ed7dfdde015f6ef63822b0224e Mon Sep 17 00:00:00 2001 From: Janne Forsman Date: Fri, 7 Feb 2025 15:47:02 +0200 Subject: [PATCH] feat: Add id field to TrafficControlDeviceType export file * code field still remains as the key field. * id field is not used when importing, it is there in the export file just to give more information Refs: LIIK-684 --- traffic_control/resources/device_type.py | 28 ++++++++++++++++++- .../test_device_type_import_export.py | 6 +++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/traffic_control/resources/device_type.py b/traffic_control/resources/device_type.py index c74d26e5..75eb30c3 100644 --- a/traffic_control/resources/device_type.py +++ b/traffic_control/resources/device_type.py @@ -1,9 +1,23 @@ -from import_export.resources import ModelResource +from import_export.resources import Diff, ModelResource from traffic_control.models import TrafficControlDeviceType from traffic_control.resources.common import EnumFieldResourceMixin +class TrafficControlDeviceTypeDiff(Diff): + """Diff wrapper not to show ID field in preview + This is abit of an hack as it overrides private function from Diff class. + Will be broken if import_export.resources.fields.Field implementation is changed so that column_name member + is renamed to something else + """ + + def _export_resource_fields(self, resource, instance): + return [ + resource.export_field(f, instance) if instance else "" + for f in filter(lambda x: x.column_name != "id", resource.get_user_visible_fields()) + ] + + class TrafficControlDeviceTypeResource(EnumFieldResourceMixin, ModelResource): """Traffic control device type resource for import/export.""" @@ -21,6 +35,7 @@ class Meta: "target_model", "type", "content_schema", + "id", ) export_order = fields clean_model_instances = True @@ -35,3 +50,14 @@ class Meta: "legacy_description": {"allow_blank": True, "coerce_to_string": True}, } import_id_fields = ["code"] + + def before_import(self, dataset, using_transactions, dry_run, **kwargs): + """ID field is just informative when creating export file""" + del dataset["id"] + + def get_diff_class(self): + return TrafficControlDeviceTypeDiff + + def get_diff_headers(self): + """Just to remove id column from import preview""" + return list(filter(lambda x: x != "id", super().get_diff_headers())) diff --git a/traffic_control/tests/test_import_export/test_device_type_import_export.py b/traffic_control/tests/test_import_export/test_device_type_import_export.py index 3186caa3..1daf8447 100644 --- a/traffic_control/tests/test_import_export/test_device_type_import_export.py +++ b/traffic_control/tests/test_import_export/test_device_type_import_export.py @@ -85,6 +85,7 @@ def test__traffic_control_device_type__export( # noqa: C901 assert dataset.dict[0]["value"] == dt.value assert dataset.dict[0]["unit"] == dt.unit assert dataset.dict[0]["size"] == dt.size + assert dataset.dict[0]["id"] == str(dt.id) # Nullable fields are "" when value is None if legacy_code: @@ -179,7 +180,7 @@ def test__traffic_control_device_type__import( if content_schema: kwargs["content_schema"] = content_schema - get_traffic_control_device_type(**kwargs) + orig_uuid = get_traffic_control_device_type(**kwargs).id dataset = get_import_dataset(TrafficControlDeviceTypeResource, format=format) TrafficControlDeviceType.objects.all().delete() @@ -202,6 +203,8 @@ def test__traffic_control_device_type__import( assert imported_dt.legacy_description == legacy_description assert imported_dt.target_model == target_model assert imported_dt.type == dt_type + # id in import phase should be ignored + assert imported_dt.id != orig_uuid @pytest.mark.parametrize("format", file_formats) @@ -330,3 +333,4 @@ def test__traffic_control_device_type__import__update( assert imported_dt.target_model == to_values["target_model"] assert imported_dt.type == to_values["type"] assert imported_dt.content_schema == to_values["content_schema"] + assert imported_dt.id == device_type.id