From d023c5d53c16fe33f424e519c021b2fd16affd70 Mon Sep 17 00:00:00 2001 From: Valentin Deniaud Date: Thu, 13 Feb 2020 15:25:24 +0100 Subject: [PATCH] misc: allow importing objects with non existent fields (#39768) --- combo/apps/assets/models.py | 2 +- combo/apps/gallery/models.py | 7 ++++--- combo/apps/maps/models.py | 2 +- combo/apps/pwa/models.py | 5 +++-- combo/data/models.py | 9 ++++++--- tests/test_import_export.py | 15 ++++++++++++++- 6 files changed, 29 insertions(+), 11 deletions(-) diff --git a/combo/apps/assets/models.py b/combo/apps/assets/models.py index 815678e..0020246 100644 --- a/combo/apps/assets/models.py +++ b/combo/apps/assets/models.py @@ -51,5 +51,5 @@ class Asset(models.Model): json_asset['model'] = 'assets.asset' asset, created = Asset.objects.get_or_create(key=json_asset['fields']['key']) json_asset['pk'] = asset.id - asset = [x for x in serializers.deserialize('json', json.dumps([json_asset]))][0] + asset = next(serializers.deserialize('json', json.dumps([json_asset]), ignorenonexistent=True)) asset.save() diff --git a/combo/apps/gallery/models.py b/combo/apps/gallery/models.py index cd1ee90..67214d8 100644 --- a/combo/apps/gallery/models.py +++ b/combo/apps/gallery/models.py @@ -43,9 +43,10 @@ class GalleryCell(CellBase): return {'images': [x.get_as_serialized_object() for x in self.image_set.all()]} def import_subobjects(self, cell_json): - for image in cell_json['images']: - image['fields']['gallery_id'] = self.id - for image in serializers.deserialize('json', json.dumps(cell_json['images'])): + images = serializers.deserialize('json', json.dumps(cell_json['images']), + ignorenonexistent=True) + for image in images: + image.object.gallery_id = self.id image.save() diff --git a/combo/apps/maps/models.py b/combo/apps/maps/models.py index c28cab6..2582299 100644 --- a/combo/apps/maps/models.py +++ b/combo/apps/maps/models.py @@ -152,7 +152,7 @@ class MapLayer(models.Model): json_layer['model'] = 'maps.maplayer' layer, created = MapLayer.objects.get_or_create(slug=json_layer['fields']['slug']) json_layer['pk'] = layer.id - layer = [x for x in serializers.deserialize('json', json.dumps([json_layer]))][0] + layer = next(serializers.deserialize('json', json.dumps([json_layer]), ignorenonexistent=True)) layer.save() def get_geojson(self, request=None, multiple_layers=False): diff --git a/combo/apps/pwa/models.py b/combo/apps/pwa/models.py index 49afb5e..e8aca23 100644 --- a/combo/apps/pwa/models.py +++ b/combo/apps/pwa/models.py @@ -159,14 +159,15 @@ class PwaNavigationEntry(models.Model): def load_serialized_object(cls, json_entry): json_entry['model'] = 'pwa.pwanavigationentry' # deserialize once to get link_page by natural key - fake_entry = [x for x in serializers.deserialize('json', json.dumps([json_entry]))][0] + fake_entry = next(serializers.deserialize('json', json.dumps([json_entry]), + ignorenonexistent=True)) entry, created = cls.objects.get_or_create( label=json_entry['fields']['label'], url=json_entry['fields']['url'], link_page=fake_entry.object.link_page, defaults={'order': 0}) json_entry['pk'] = entry.id - entry = [x for x in serializers.deserialize('json', json.dumps([json_entry]))][0] + entry = next(serializers.deserialize('json', json.dumps([json_entry]), ignorenonexistent=True)) entry.save() if json_entry.get('icon:base64'): decode = base64.decodestring if six.PY2 else base64.decodebytes diff --git a/combo/data/models.py b/combo/data/models.py index 429b1cd..bc1cf4e 100644 --- a/combo/data/models.py +++ b/combo/data/models.py @@ -392,7 +392,7 @@ class Page(models.Model): json_page['fields']['groups'] = [[x] for x in json_page['fields']['groups'] if isinstance(x, six.string_types)] page, created = Page.objects.get_or_create(slug=json_page['fields']['slug'], snapshot=snapshot) json_page['pk'] = page.id - page = [x for x in serializers.deserialize('json', json.dumps([json_page]))][0] + page = next(serializers.deserialize('json', json.dumps([json_page]), ignorenonexistent=True)) page.object.snapshot = snapshot page.save() for cell in json_page.get('cells'): @@ -411,7 +411,9 @@ class Page(models.Model): @classmethod def load_serialized_cells(cls, cells): # load new cells - for index, cell in enumerate(serializers.deserialize('json', json.dumps(cells))): + deserialized_cells = serializers.deserialize('json', json.dumps(cells), + ignorenonexistent=True) + for index, cell in enumerate(deserialized_cells): cell.save() # will populate cached_* attributes cell.object.save() @@ -1041,7 +1043,8 @@ class LinkListCell(CellBase): def import_subobjects(self, cell_json): for link in cell_json['links']: link['fields']['placeholder'] = self.link_placeholder - for link in serializers.deserialize('json', json.dumps(cell_json['links'])): + links = serializers.deserialize('json', json.dumps(cell_json['links']), ignorenonexistent=True) + for link in links: link.save() def duplicate_m2m(self, new_cell): diff --git a/tests/test_import_export.py b/tests/test_import_export.py index 4521d91..ff1bb65 100644 --- a/tests/test_import_export.py +++ b/tests/test_import_export.py @@ -274,5 +274,18 @@ def test_import_export_gallery_images(app, some_data): import_site(data=json.loads(output)) assert Image.objects.all().count() == 2 - assert image1.title == 'foo' + image1 = Image.objects.get(title='foo') assert image1.image == 'path/foo.jpg' + assert image1.gallery.placeholder == 'images' + +def test_import_export_extra_fields(app, some_data): + site_export = export_site() + for page in site_export['pages']: + if page['fields']['slug'] == 'one': + page['fields']['extra_field_not_in_model'] = True + elif page['fields']['slug'] == 'three': + page['cells'][0]['fields']['extra_field_not_in_model'] = True + + import_site(site_export) + assert Page.objects.count() == 3 + assert TextCell.objects.count() == 1 -- 2.20.1