| 1 | """New base serializer class to handle full serialization of model objects."""
|
|---|
| 2 | try:
|
|---|
| 3 | from cStringIO import StringIO
|
|---|
| 4 | except ImportError:
|
|---|
| 5 | from StringIO import StringIO
|
|---|
| 6 |
|
|---|
| 7 | from django.core.serializers import base
|
|---|
| 8 |
|
|---|
| 9 |
|
|---|
| 10 | class Serializer(base.Serializer):
|
|---|
| 11 | """Serializer for Django models inspired by Ruby on Rails serializer.
|
|---|
| 12 |
|
|---|
| 13 | """
|
|---|
| 14 |
|
|---|
| 15 | def __init__(self, *args, **kwargs):
|
|---|
| 16 | """Declare instance attributes."""
|
|---|
| 17 | self.options = None
|
|---|
| 18 | self.stream = None
|
|---|
| 19 | self.fields = None
|
|---|
| 20 | self.excludes = None
|
|---|
| 21 | self.relations = None
|
|---|
| 22 | self.extras = None
|
|---|
| 23 | super(Serializer, self).__init__(*args, **kwargs)
|
|---|
| 24 |
|
|---|
| 25 | def serialize(self, queryset, **options):
|
|---|
| 26 | """Serialize a queryset with the following options allowed:
|
|---|
| 27 | fields - list of fields to be serialized. If not provided then all
|
|---|
| 28 | fields are serialized.
|
|---|
| 29 | excludes - list of fields to be excluded. Overrides ``fields``.
|
|---|
| 30 | relations - list of related fields to be fully serialized.
|
|---|
| 31 | extras - list of attributes and methods to include.
|
|---|
| 32 | Methods cannot take arguments.
|
|---|
| 33 | """
|
|---|
| 34 | self.options = options
|
|---|
| 35 | self.stream = options.get("stream", StringIO())
|
|---|
| 36 | self.fields = options.get("fields", [])
|
|---|
| 37 | self.excludes = options.get("excludes", [])
|
|---|
| 38 | self.relations = options.get("relations", [])
|
|---|
| 39 | self.extras = options.get("extras", [])
|
|---|
| 40 |
|
|---|
| 41 | self.start_serialization()
|
|---|
| 42 | for obj in queryset:
|
|---|
| 43 | self.start_object(obj)
|
|---|
| 44 | for field in obj._meta.local_fields:
|
|---|
| 45 | attname = field.attname
|
|---|
| 46 | if field.serialize:
|
|---|
| 47 | if field.rel is None:
|
|---|
| 48 | if attname not in self.excludes:
|
|---|
| 49 | if not self.fields or attname in self.fields:
|
|---|
| 50 | self.handle_field(obj, field)
|
|---|
| 51 | else:
|
|---|
| 52 | if attname[:-3] not in self.excludes:
|
|---|
| 53 | if not self.fields or attname[:-3] in self.fields:
|
|---|
| 54 | self.handle_fk_field(obj, field)
|
|---|
| 55 | for field in obj._meta.many_to_many:
|
|---|
| 56 | if field.serialize:
|
|---|
| 57 | if field.attname not in self.excludes:
|
|---|
| 58 | if not self.fields or field.attname in self.fields:
|
|---|
| 59 | self.handle_m2m_field(obj, field)
|
|---|
| 60 | for extra in self.extras:
|
|---|
| 61 | self.handle_extra_field(obj, extra)
|
|---|
| 62 | self.end_object(obj)
|
|---|
| 63 | self.end_serialization()
|
|---|
| 64 | return self.getvalue()
|
|---|
| 65 |
|
|---|
| 66 | def handle_extra_field(self, obj, extra):
|
|---|
| 67 | """Called to handle 'extras' field serialization."""
|
|---|
| 68 | raise NotImplementedError
|
|---|