Django app that automates objects tree serialization recursively
Project 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}
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Close
Hashes for django-auto-serializer-0.4.2.tar.gz
Algorithm | Hash digest | |
---|---|---|
SHA256 | 4bf2a8f89c6bb42a9331af33f6140e4eed836116c94e28fd511566a126c6670a |
|
MD5 | 009ce0e99ea1f2c490abda5afa0066cb |
|
BLAKE2b-256 | a06fd011b5be5b735602a697183d68e5f66e0b9bd17f24bc7191962352e163ad |