From 9c92f96ce2299667ef3393c6d63ffe7a83c89e4a Mon Sep 17 00:00:00 2001 From: Shawn Lewis Date: Thu, 23 Feb 2012 16:30:44 -0800 Subject: Fix for #178. Related serializers passed in via include now work as expected. --- djangorestframework/serializer.py | 29 +++++++---------------------- 1 file changed, 7 insertions(+), 22 deletions(-) (limited to 'djangorestframework/serializer.py') diff --git a/djangorestframework/serializer.py b/djangorestframework/serializer.py index b0c02675..5dea37e8 100644 --- a/djangorestframework/serializer.py +++ b/djangorestframework/serializer.py @@ -25,16 +25,9 @@ def _field_to_tuple(field): def _fields_to_list(fields): """ - Return a list of field names. + Return a list of field tuples. """ - return [_field_to_tuple(field)[0] for field in fields or ()] - - -def _fields_to_dict(fields): - """ - Return a `dict` of field name -> None, or tuple of fields, or Serializer class - """ - return dict([_field_to_tuple(field) for field in fields or ()]) + return [_field_to_tuple(field) for field in fields or ()] class _SkipField(Exception): @@ -110,9 +103,6 @@ class Serializer(object): self.stack = stack def get_fields(self, obj): - """ - Return the set of field names/keys to use for a model instance/dict. - """ fields = self.fields # If `fields` is not set, we use the default fields and modify @@ -123,9 +113,6 @@ class Serializer(object): exclude = self.exclude or () fields = set(default + list(include)) - set(exclude) - else: - fields = _fields_to_list(self.fields) - return fields def get_default_fields(self, obj): @@ -139,9 +126,7 @@ class Serializer(object): else: return obj.keys() - def get_related_serializer(self, key): - info = _fields_to_dict(self.fields).get(key, None) - + def get_related_serializer(self, info): # If an element in `fields` is a 2-tuple of (str, tuple) # then the second element of the tuple is the fields to # set on the related serializer @@ -175,11 +160,11 @@ class Serializer(object): """ return self.rename.get(smart_str(key), smart_str(key)) - def serialize_val(self, key, obj): + def serialize_val(self, key, obj, related_info): """ Convert a model field or dict value into a serializable representation. """ - related_serializer = self.get_related_serializer(key) + related_serializer = self.get_related_serializer(related_info) if self.depth is None: depth = None @@ -219,7 +204,7 @@ class Serializer(object): fields = self.get_fields(instance) # serialize each required field - for fname in fields: + for fname, related_info in _fields_to_list(fields): try: # we first check for a method 'fname' on self, # 'fname's signature must be 'def fname(self, instance)' @@ -237,7 +222,7 @@ class Serializer(object): continue key = self.serialize_key(fname) - val = self.serialize_val(fname, obj) + val = self.serialize_val(fname, obj, related_info) data[key] = val except _SkipField: pass -- cgit v1.2.3 From 54a19105f051113085efe9f87783acb77127c1d1 Mon Sep 17 00:00:00 2001 From: Alen Mujezinovic Date: Thu, 1 Mar 2012 12:46:38 +0000 Subject: Maintain a reference to the parent serializer when descending down into fields --- djangorestframework/serializer.py | 1 + 1 file changed, 1 insertion(+) (limited to 'djangorestframework/serializer.py') diff --git a/djangorestframework/serializer.py b/djangorestframework/serializer.py index 5dea37e8..e2d860a2 100644 --- a/djangorestframework/serializer.py +++ b/djangorestframework/serializer.py @@ -133,6 +133,7 @@ class Serializer(object): if isinstance(info, (list, tuple)): class OnTheFlySerializer(self.__class__): fields = info + parent = getattr(self, 'parent', self) return OnTheFlySerializer # If an element in `fields` is a 2-tuple of (str, Serializer) -- cgit v1.2.3 From 0a57cf98766ebbf22900024608faefbca3bdde6b Mon Sep 17 00:00:00 2001 From: Alen Mujezinovic Date: Thu, 1 Mar 2012 12:51:23 +0000 Subject: Added a .parent attribute to the Serializer object for documentation purposes --- djangorestframework/serializer.py | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'djangorestframework/serializer.py') diff --git a/djangorestframework/serializer.py b/djangorestframework/serializer.py index e2d860a2..f30667f1 100644 --- a/djangorestframework/serializer.py +++ b/djangorestframework/serializer.py @@ -96,6 +96,11 @@ class Serializer(object): """ The maximum depth to serialize to, or `None`. """ + + parent = None + """ + A reference to the root serializer when descending down into fields. + """ def __init__(self, depth=None, stack=[], **kwargs): if depth is not None: -- cgit v1.2.3 From 537fa19bacd97743555b3cac2a3e3c6e14786124 Mon Sep 17 00:00:00 2001 From: Alen Mujezinovic Date: Thu, 1 Mar 2012 13:17:29 +0000 Subject: Whoops. Adding the .parent attribute to the Serializer class broke getattr(self,'parent',self). This fixes it. --- djangorestframework/serializer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'djangorestframework/serializer.py') diff --git a/djangorestframework/serializer.py b/djangorestframework/serializer.py index f30667f1..d000ad96 100644 --- a/djangorestframework/serializer.py +++ b/djangorestframework/serializer.py @@ -138,7 +138,7 @@ class Serializer(object): if isinstance(info, (list, tuple)): class OnTheFlySerializer(self.__class__): fields = info - parent = getattr(self, 'parent', self) + parent = getattr(self, 'parent') or self return OnTheFlySerializer # If an element in `fields` is a 2-tuple of (str, Serializer) -- cgit v1.2.3 From b689db17b3c1ef5a2bca3a7fa90d3381bd5ba4fe Mon Sep 17 00:00:00 2001 From: Max Arnold Date: Tue, 22 May 2012 12:39:50 +0700 Subject: Allow RawQuerySet serialization --- djangorestframework/serializer.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'djangorestframework/serializer.py') diff --git a/djangorestframework/serializer.py b/djangorestframework/serializer.py index 5dea37e8..9481eeff 100644 --- a/djangorestframework/serializer.py +++ b/djangorestframework/serializer.py @@ -2,7 +2,7 @@ Customizable serialization. """ from django.db import models -from django.db.models.query import QuerySet +from django.db.models.query import QuerySet, RawQuerySet from django.utils.encoding import smart_unicode, is_protected_type, smart_str import inspect @@ -261,7 +261,7 @@ class Serializer(object): if isinstance(obj, (dict, models.Model)): # Model instances & dictionaries return self.serialize_model(obj) - elif isinstance(obj, (tuple, list, set, QuerySet, types.GeneratorType)): + elif isinstance(obj, (tuple, list, set, QuerySet, RawQuerySet, types.GeneratorType)): # basic iterables return self.serialize_iter(obj) elif isinstance(obj, models.Manager): -- cgit v1.2.3 From 1b49c5e3e5c1b33d8d4c2dcaaaf6cb4dcbffa814 Mon Sep 17 00:00:00 2001 From: Sean C. Farley Date: Tue, 26 Jun 2012 19:27:57 -0400 Subject: Pass request to related serializers Related serializers may need access to the request to properly serialize a child resource. For example, reverse() in djangorestframework.reverse uses request if available to return an absolute URL. While the parent resource has access to the request to generate the absolute URL, the child resource does not. --- djangorestframework/serializer.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'djangorestframework/serializer.py') diff --git a/djangorestframework/serializer.py b/djangorestframework/serializer.py index 9481eeff..ffe9d8cb 100644 --- a/djangorestframework/serializer.py +++ b/djangorestframework/serializer.py @@ -179,7 +179,8 @@ class Serializer(object): stack = self.stack[:] stack.append(obj) - return related_serializer(depth=depth, stack=stack).serialize(obj) + return related_serializer(depth=depth, stack=stack).serialize( + obj, request=self.request) def serialize_max_depth(self, obj): """ @@ -253,11 +254,15 @@ class Serializer(object): """ return smart_unicode(obj, strings_only=True) - def serialize(self, obj): + def serialize(self, obj, request=None): """ Convert any object into a serializable representation. """ + # Request from related serializer. + if request is not None: + self.request = request + if isinstance(obj, (dict, models.Model)): # Model instances & dictionaries return self.serialize_model(obj) -- cgit v1.2.3 From 11147ce13e754f47b9cdc8d0de8a071aa540882f Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Thu, 28 Jun 2012 14:16:30 +0200 Subject: Don't bork if request attribute is not set. --- djangorestframework/serializer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'djangorestframework/serializer.py') diff --git a/djangorestframework/serializer.py b/djangorestframework/serializer.py index ffe9d8cb..027c9daf 100644 --- a/djangorestframework/serializer.py +++ b/djangorestframework/serializer.py @@ -180,7 +180,7 @@ class Serializer(object): stack.append(obj) return related_serializer(depth=depth, stack=stack).serialize( - obj, request=self.request) + obj, request=getattr(self, 'request', None)) def serialize_max_depth(self, obj): """ -- cgit v1.2.3 From 2f9775c12d172199c2a915062bfba3a13f5cadc4 Mon Sep 17 00:00:00 2001 From: Alen Mujezinovic Date: Mon, 13 Aug 2012 15:58:23 +0100 Subject: Don't ever return the normal serializer again. --- djangorestframework/serializer.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'djangorestframework/serializer.py') diff --git a/djangorestframework/serializer.py b/djangorestframework/serializer.py index d000ad96..f2f89f6c 100644 --- a/djangorestframework/serializer.py +++ b/djangorestframework/serializer.py @@ -135,10 +135,12 @@ class Serializer(object): # If an element in `fields` is a 2-tuple of (str, tuple) # then the second element of the tuple is the fields to # set on the related serializer + + class OnTheFlySerializer(self.__class__): + fields = info + parent = getattr(self, 'parent') or self + if isinstance(info, (list, tuple)): - class OnTheFlySerializer(self.__class__): - fields = info - parent = getattr(self, 'parent') or self return OnTheFlySerializer # If an element in `fields` is a 2-tuple of (str, Serializer) @@ -156,8 +158,9 @@ class Serializer(object): elif isinstance(info, str) and info in _serializers: return _serializers[info] - # Otherwise use `related_serializer` or fall back to `Serializer` - return getattr(self, 'related_serializer') or Serializer + # Otherwise use `related_serializer` or fall back to + # `OnTheFlySerializer` preserve custom serialization methods. + return getattr(self, 'related_serializer') or OnTheFlySerializer def serialize_key(self, key): """ -- cgit v1.2.3