diff options
Diffstat (limited to 'ishtar_common')
-rw-r--r-- | ishtar_common/serializers.py | 32 | ||||
-rw-r--r-- | ishtar_common/tests.py | 32 |
2 files changed, 52 insertions, 12 deletions
diff --git a/ishtar_common/serializers.py b/ishtar_common/serializers.py index 6f3cf095d..2069c7e38 100644 --- a/ishtar_common/serializers.py +++ b/ishtar_common/serializers.py @@ -9,7 +9,7 @@ from zipfile import ZipFile from django.apps import apps from django.contrib.sites.models import Site -from django.core.serializers import serialize +from django.core.serializers import deserialize, serialize from version import get_version from . import models @@ -62,11 +62,34 @@ def type_serialization(archive=False, return_empty_types=False, continue model_name = model.__name__ model_name = str(model.__module__).split(".")[0] + "__" + model_name + base_q = model.objects + q = base_q + recursion = None + if hasattr(model, "parent"): + recursion = "parent" + elif hasattr(model, "inverse_relation"): + recursion = "inverse_relation" + if recursion: + q = q.filter(**{recursion + "__isnull": True}) result[model_name] = serialize( - "json", model.objects.all(), + "json", q.all(), indent=2, use_natural_foreign_keys=True, use_natural_primary_keys=True ) + if recursion: + serialized = [item["id"] for item in q.values("id").all()] + q = base_q.filter(**{recursion + "_id__in": serialized} + ).exclude(id__in=serialized) + while q.count(): + v = serialize( + "json", q.all(), indent=2, use_natural_foreign_keys=True, + use_natural_primary_keys=True) + new_result = json.loads(result[model_name]) + new_result += json.loads(v) + result[model_name] = json.dumps(new_result, indent=2) + serialized += [item["id"] for item in q.values("id").all()] + q = base_q.filter(**{recursion + "_id__in": serialized} + ).exclude(id__in=serialized) if return_empty_types: return [k for k in result if not result[k]] if not archive: @@ -115,6 +138,9 @@ def restore_serialized(archive_name, delete_existing=False): path = json_filename.split(os.sep) if len(path) != 2 or path[0] != "types": continue - model = get_model_from_filename(path[-1]) if delete_existing: + model = get_model_from_filename(path[-1]) model.objects.all().delete() + data = zip_file.read(json_filename).decode("utf-8") + for obj in deserialize("json", data): + obj.save() diff --git a/ishtar_common/tests.py b/ishtar_common/tests.py index 03c2ad03a..e292ae097 100644 --- a/ishtar_common/tests.py +++ b/ishtar_common/tests.py @@ -632,16 +632,30 @@ class SerializationTest(TestCase): restore_serialized(zip_filename) def test_type_restore(self): + models.AuthorType.objects.create(label="Test", txt_idx="test") + zip_filename = type_serialization(archive=True) - initial_count = {} - with zipfile.ZipFile(zip_filename, "r") as zip_file: - for json_filename in zip_file.namelist(): - path = json_filename.split(os.sep) - if len(path) != 2 or path[0] != "types": - continue - model = get_model_from_filename(path[-1]) - initial_count[json_filename] = model.objects.count() - model.objects.all().delete() + models.AuthorType.objects.create( + label="Am I still here", txt_idx="am-i-still-here") + models.AuthorType.objects.filter(txt_idx="test").delete() + restore_serialized(zip_filename) + self.assertEqual( + models.AuthorType.objects.filter(txt_idx="test").count(), 1) + self.assertEqual( + models.AuthorType.objects.filter(txt_idx="am-i-still-here").count(), + 1) + + models.AuthorType.objects.filter(txt_idx="am-i-still-here").delete() + zip_filename = type_serialization(archive=True) + models.AuthorType.objects.create( + label="Am I still here", txt_idx="am-i-still-here") + models.AuthorType.objects.filter(txt_idx="test").delete() + restore_serialized(zip_filename, delete_existing=True) + self.assertEqual( + models.AuthorType.objects.filter(txt_idx="test").count(), 1) + self.assertEqual( + models.AuthorType.objects.filter(txt_idx="am-i-still-here").count(), + 0) class AccessControlTest(TestCase): |