Metadata-Version: 2.1
Name: django-auto-serializer
Version: 0.4.2
Summary: Django app that automates objects tree serialization recursively
Home-page: https://github.com/peppelinux/django-auto-serializer
Author: Giuseppe De Marco
Author-email: giuseppe.demarco@unical.it
License: BSD
Description: # Django auto-serializer
        Django app that automates objects tree serialization recursively, without any declarations.
        
        Define new classes for every Object serialization could sound a bit boring, I coded this app to do the things automagically.
        Django-auto-serializer will do for you:
        
        - Json serialization (export);
        - recursively serialize all FK childrens;
        - can ignore some children if you tell him how they are named (see examples above);
        - M2M auto serialization;
        - ignore or not autofields import/export (auto_now_add...);
        - regenerates unique if needed, the same for slugfields (change_uniques = True,);
        - Import a serialized Object tree, it will build up everything as before;
        
        ## Setup
        ````
        pip install git+https://github.com/peppelinux/django-auto-serializer.git
        ````
        
        ## Usage Example
        ````
        from my_app.models import MyModel
        
        # get an object
        myObj = MyModel.objects.first()
        
        # object serialization
        # A single object duplication
        si = SerializableInstance(myObj)
        
        #si.serialize_obj()
        si.serialize_tree()
        si.remove_duplicates()
        # pprint(si.dict)
        
        # Serialized entire tree, main object with childrens
        si = SerializableInstance(myObj,
                                  excluded_fields=['field1', 'field2'],
                                  excluded_childrens = ['relatedObjClass1', 'relatedObjClass2'],
                                  auto_fields = False,
                                  change_uniques = True,
                                  duplicate = True)
        si.serialize_tree()
        si.remove_duplicates()
        ````
        
        ## Some coding hints
        ````
        import pprint
        # all the fields
        myObj._meta._forward_fields_map
        
        # childrens here
        myObj._meta.fields_map
        myObj._meta.related_objects
        
        # another way with NestedObjects
        from django.contrib.admin.utils import NestedObjects
        from django.db import DEFAULT_DB_ALIAS
        
        # get json with pk and autofilled fields as they are
        from django.core import serializers
        serializers.serialize('json', [myObj], ensure_ascii=False)
        
        # serializers.serialize() relies on
        model_to_dict(myObj)
        
        pprint(sit.dict)
        for i in sit.dict['childrens']:
            if i['model_name'] == 'ClassName':
                pprint(i)
        
        tree_to_str = json.dumps(si.dict, indent=2)
        jsonstr_to_dict = json.loads(tree_to_str)
        pprint(jsonstr_to_dict )
        ````
        
        ## Import dump
        ````
        isi = ImportableSerializedInstance(si.dict)
        isi.save()
        print(isi.json())
        ````
        
        ## A simple view to import a json dump
        ````
        @user_passes_test(lambda u:u.is_staff)
        def import_file(request):
            file_to_import = request.FILES.get('file_to_import')
            # content here
            url = reverse('admin:my_django_admin_url')
            if not file_to_import:
                return HttpResponseRedirect(url)
            if not file_to_import:
                # error message here
                pass
            jcont = json.loads(request.FILES['file_to_import'].read().decode(settings.DEFAULT_CHARSET))
            isi = ImportableSerializedInstance(jcont)
            isi.save()
            return HttpResponseRedirect(url)
        ````
        
        ## Django admin action to duplicate or export an entire tree
        ````
        import io
        import json
        
        from django.apps import apps
        from django.contrib import messages
        from django.contrib.admin.models import LogEntry, ADDITION, CHANGE
        from django.contrib.contenttypes.models import ContentType
        from django.http.response import HttpResponse
        
        from django_auto_serializer.auto_serializer import (SerializableInstance,
                                                            ImportableSerializedInstance)
        
        from .models import *
        
        
        def my_clone_func(modeladmin, request, queryset):
            for myObj in queryset:
                try:
                    si = SerializableInstance(myObj)
                    si.serialize_tree()
                    si.remove_duplicates()
                except Exception as e:
                    msg = '{} cloning failed: {}'
                    messages.add_message(request, messages.WARNING,
                                         msg.format(myObj, e))
                try:
                    isi = ImportableSerializedInstance(si.dict)
                    isi.save()
                except Exception as e:
                    msg = '{} cloning failed: {}'
                    messages.add_message(request, messages.WARNING,
                                         msg.format(myObj, e))
        
                msg = '{} successfully cloned.'
                messages.add_message(request, messages.INFO,
                                     msg.format(myObj))
        my_clone_func.short_description = "Clone object and its configuration"
        
        
        def download_obj_template(modeladmin, request, queryset):
            iofile = io.StringIO()
            obj_labels = []
            for myObj in queryset:
                try:
                    si = SerializableInstance(myObj)
                    st = si.serialize_tree()
                    iofile.write(json.dumps(si.dict, indent=2))
                except Exception as e:
                    msg = '{} cloning failed: {}'
                    messages.add_message(request, messages.WARNING,
                                         msg.format(myObj, e))
                obj_labels.append(myObj.__str__())
            file_name = 'my_export{}.json'.format('_'.join(obj_labels))
            iofile.seek(0)
            response = HttpResponse(iofile.read())
            response['content_type'] = 'application/force-download'
            response['Content-Disposition'] = 'attachment; filename={}'.format(file_name)
            response['X-Sendfile'] = file_name
            return response
        download_obj_template.short_description = "Download object json template"
        ````
        
        ## Result (from a real NavigationBar object with items and items childs)
        ````
        {'source_pk': 266,
         'duplicate': True,
         'app_name': 'cmsmenus',
         'model_name': 'NavigationBar',
         'object': {'created_by': 2,
          'created_by_id': 2,
          'is_active': True,
          'name': 'test'},
         'm2m': [],
         'childrens': [{'source_pk': 1603,
           'duplicate': True,
           'app_name': 'cmsmenus',
           'model_name': 'NavigationBarItem',
           'object': {'created_by': 2,
            'created_by_id': 2,
            'order': 1,
            'is_active': True,
            'name': 'child 1',
            'parent': 1602,
            'parent_id': 1602,
            'url': 'None'},
           'm2m': [],
           'childrens': [{'source_pk': 1604,
             'duplicate': True,
             'app_name': 'cmsmenus',
             'model_name': 'NavigationBarItem',
             'object': {'created_by': 2,
              'created_by_id': 2,
              'order': 2,
              'is_active': True,
              'menu': 266,
              'menu_id': 266,
              'name': 'child 2',
              'url': 'None'},
             'm2m': [],
             'childrens': [],
             'depth': 2,
             'save': False,
             'related_field': 'parent'}],
           'depth': 1,
           'save': False,
           'related_field': 'menu'},
          {'source_pk': 1604,
           'duplicate': True,
           'app_name': 'cmsmenus',
           'model_name': 'NavigationBarItem',
           'object': {'created_by': 2,
            'created_by_id': 2,
            'order': 2,
            'is_active': True,
            'name': 'child 2',
            'parent': 1603,
            'parent_id': 1603,
            'url': 'None'},
           'm2m': [],
           'childrens': [],
           'depth': 1,
           'save': False,
           'related_field': 'menu'},
          {'source_pk': 1602,
           'duplicate': True,
           'app_name': 'cmsmenus',
           'model_name': 'NavigationBarItem',
           'object': {'created_by': 2,
            'created_by_id': 2,
            'modified_by': 2,
            'modified_by_id': 2,
            'order': 10,
            'is_active': True,
            'name': 'parent',
            'url': 'None'},
           'm2m': [],
           'childrens': [{'source_pk': 1603,
             'duplicate': True,
             'app_name': 'cmsmenus',
             'model_name': 'NavigationBarItem',
             'object': {'created_by': 2,
              'created_by_id': 2,
              'order': 1,
              'is_active': True,
              'menu': 266,
              'menu_id': 266,
              'name': 'child 1',
              'url': 'None'},
             'm2m': [],
             'childrens': [{'source_pk': 1604,
               'duplicate': True,
               'app_name': 'cmsmenus',
               'model_name': 'NavigationBarItem',
               'object': {'created_by': 2,
                'created_by_id': 2,
                'order': 2,
                'is_active': True,
                'menu': 266,
                'menu_id': 266,
                'name': 'child 2',
                'url': 'None'},
               'm2m': [],
               'childrens': [],
               'depth': 3,
               'save': True,
               'related_field': 'parent'}],
             'depth': 2,
             'save': True,
             'related_field': 'parent'},
            {'source_pk': 35,
             'duplicate': True,
             'app_name': 'cmsmenus',
             'model_name': 'NavigationBarItemLocalization',
             'object': {'created_by': 2,
              'created_by_id': 2,
              'modified_by': 2,
              'modified_by_id': 2,
              'is_active': True,
              'language': 'en',
              'name': 'adasdasd'},
             'm2m': [],
             'childrens': [],
             'depth': 2,
             'save': True,
             'related_field': 'item'}],
           'depth': 1,
           'save': True,
           'related_field': 'menu'}],
         'depth': 0,
         'save': True}
        ````
        
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: License :: OSI Approved :: BSD License
Classifier: Programming Language :: Python :: 3 :: Only
Description-Content-Type: text/markdown
