Skip to content

Instantly share code, notes, and snippets.

@peterdemin
Created July 15, 2013 04:59
Show Gist options
  • Save peterdemin/5997609 to your computer and use it in GitHub Desktop.
Save peterdemin/5997609 to your computer and use it in GitHub Desktop.
Abstract django model serializer. Instead of flat structure, allows using hierarchies. You must override Model in descendants. Constructor works in two ways: 1. Passing only model instance - serializes it to dict (self.data); 2. Passing both instance and data - in that order - deserializes data into passed instance. See attached usage.py for exa…
import os
from django.db import models
class SimpleSerializer(object):
Model = None
exclude = ()
ingored_fields = (
models.AutoField,
models.ForeignKey,
models.fields.related.RelatedField,
)
def __init__(self, instance_or_dict, instance=None):
if instance is None:
self.serialize(instance_or_dict)
else:
self.deserialize(instance_or_dict, instance)
def serialize(self, instance):
exclude = set(self.exclude)
self.data = {}
for field in self.Model._meta.fields:
if field.name in exclude:
continue
if isinstance(field, self.ingored_fields):
continue
if field.primary_key:
continue
self.data[field.name] = getattr(instance, field.name)
def deserialize(self, data, instance):
field_names = set([field.name for field in self.Model._meta.fields])
field_names.difference_update(set(self.exclude))
for key in data:
if key in field_names:
setattr(instance, key, data[key])
from course.models import Course
from core.serializers import SimpleSerializer
from exercise.serializers import BlockSerializer
class CourseSerializer(SimpleSerializer):
Model = Course
exclude = ('blocks',)
def serialize(self, instance):
super(CourseSerializer, self).serialize(instance)
self.data['blocks'] = self.serialize_blocks(instance)
def serialize_blocks(self, instance):
for block in instance.blocks.all():
yield BlockSerializer(block).data
def deserialize(self, data, instance):
super(CourseSerializer, self).deserialize(data, instance)
for block_data in data['blocks']:
block = Block(org=instance.org)
BlockSerializer(block_data, block)
instance.append_block(block)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment