|
| 1 | +import base64 |
| 2 | +import io |
| 3 | + |
| 4 | +from django.core.files import File as DjangoFile |
| 5 | +from django.core.serializers import base |
| 6 | +from django.core.serializers.python import ( |
| 7 | + Serializer as PythonSerializer, |
| 8 | + Deserializer as PythonDeserializer, |
| 9 | + _get_model, |
| 10 | +) |
| 11 | + |
| 12 | +try: |
| 13 | + from filer.fields.image import FilerImageField |
| 14 | + from filer.models import Image |
| 15 | + |
| 16 | + has_filer = True |
| 17 | +except ImportError: |
| 18 | + has_filer = False |
| 19 | + |
| 20 | + |
| 21 | +class FilerImageFieldSerializer: |
| 22 | + @classmethod |
| 23 | + def serialize(cls, field_instance): |
| 24 | + serializer = Serializer() |
| 25 | + _image_plugin_data = serializer.serialize((field_instance,))[0] |
| 26 | + _file_plugin_data = serializer.serialize( |
| 27 | + (field_instance.file_ptr,), fields=["original_filename", "mime_type"] |
| 28 | + )[0] |
| 29 | + base64_image = base64.b64encode(field_instance.file.read()) |
| 30 | + |
| 31 | + _plugin_data = _image_plugin_data["fields"] |
| 32 | + _plugin_data.update(_file_plugin_data["fields"]) |
| 33 | + _plugin_data["file_content"] = base64_image.decode() |
| 34 | + return _plugin_data |
| 35 | + |
| 36 | + @classmethod |
| 37 | + def deserialize(cls, serialized_data): |
| 38 | + base64_image = base64.b64decode(serialized_data.pop("file_content")) |
| 39 | + |
| 40 | + filename = serialized_data["original_filename"] |
| 41 | + file_obj = DjangoFile(io.BytesIO(base64_image), name=filename) |
| 42 | + image = Image.objects.create( |
| 43 | + **serialized_data, |
| 44 | + file=file_obj, |
| 45 | + ) |
| 46 | + |
| 47 | + return image.pk |
| 48 | + |
| 49 | + |
| 50 | +class Serializer(PythonSerializer): |
| 51 | + def handle_fk_field(self, obj, field): |
| 52 | + if has_filer and isinstance(field, FilerImageField): |
| 53 | + field_instance = getattr(obj, field.name) |
| 54 | + self._current[field.name] = FilerImageFieldSerializer.serialize( |
| 55 | + field_instance |
| 56 | + ) |
| 57 | + else: |
| 58 | + super(Serializer, self).handle_fk_field(obj, field) |
| 59 | + |
| 60 | + |
| 61 | +def Deserializer(object_list, **options): |
| 62 | + for d in object_list: |
| 63 | + # Look up the model and starting build a dict of data for it. |
| 64 | + try: |
| 65 | + Model = _get_model(d["model"]) |
| 66 | + except base.DeserializationError: |
| 67 | + if options["ignorenonexistent"]: |
| 68 | + continue |
| 69 | + else: |
| 70 | + raise |
| 71 | + for (field_name, field_value) in d["fields"].items(): |
| 72 | + field = Model._meta.get_field(field_name) |
| 73 | + if has_filer and isinstance(field, FilerImageField): |
| 74 | + value = FilerImageFieldSerializer.deserialize(field_value) |
| 75 | + d["fields"][field_name] = value |
| 76 | + |
| 77 | + yield from PythonDeserializer(object_list, **options) |
0 commit comments