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
|
---|