diff --git a/.gitignore b/.gitignore index 312b28df9..3472a5dd5 100644 --- a/.gitignore +++ b/.gitignore @@ -21,4 +21,5 @@ MANIFEST .coverage .tox .DS_Store -.idea/* \ No newline at end of file +.idea/* +/djangorestframework/.idea/ \ No newline at end of file diff --git a/djangorestframework/mixins.py b/djangorestframework/mixins.py index 9fed61221..2b3ced407 100644 --- a/djangorestframework/mixins.py +++ b/djangorestframework/mixins.py @@ -264,6 +264,7 @@ class ResponseMixin(object): resp = HttpResponse(content, mimetype=response.media_type, status=response.status) for (key, val) in response.headers.items(): resp[key] = val + resp['Content-Length'] = len(content) return resp @@ -444,11 +445,11 @@ class ResourceMixin(object): """ return self._resource.validate_request(data, files) - def filter_response(self, obj): + def filter_response(self, obj, request=None): """ Given the response content, filter it into a serializable object. """ - return self._resource.filter_response(obj) + return self._resource.filter_response(obj, request) def get_bound_form(self, content=None, method=None): return self._resource.get_bound_form(content, method=method) diff --git a/djangorestframework/resources.py b/djangorestframework/resources.py index 5770d07f9..197fd58df 100644 --- a/djangorestframework/resources.py +++ b/djangorestframework/resources.py @@ -35,11 +35,11 @@ class BaseResource(Serializer): """ return data - def filter_response(self, obj): + def filter_response(self, obj, request=None): """ Given the response content, filter it into a serializable object. """ - return self.serialize(obj) + return self.serialize(obj, request) class Resource(BaseResource): diff --git a/djangorestframework/serializer.py b/djangorestframework/serializer.py index 55b84df16..582de70a1 100644 --- a/djangorestframework/serializer.py +++ b/djangorestframework/serializer.py @@ -173,7 +173,7 @@ class Serializer(object): return getattr(self, 'related_serializer') or Serializer - def serialize_key(self, key): + def serialize_key(self, key, request=None): """ Keys serialize to their string value, unless they exist in the `rename` dict. @@ -181,7 +181,7 @@ 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, request=None): """ Convert a model field or dict value into a serializable representation. """ @@ -190,20 +190,20 @@ class Serializer(object): if self.depth is None: depth = None elif self.depth <= 0: - return self.serialize_max_depth(obj) + return self.serialize_max_depth(obj, request) else: depth = self.depth - 1 if any([obj is elem for elem in self.stack]): - return self.serialize_recursion(obj) + return self.serialize_recursion(obj, request) else: 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) - def serialize_max_depth(self, obj): + def serialize_max_depth(self, obj, request=None): """ Determine how objects should be serialized once `depth` is exceeded. The default behavior is to ignore the field. @@ -211,7 +211,7 @@ class Serializer(object): raise _SkipField - def serialize_recursion(self, obj): + def serialize_recursion(self, obj, request=None): """ Determine how objects should be serialized if recursion occurs. The default behavior is to ignore the field. @@ -219,7 +219,7 @@ class Serializer(object): raise _SkipField - def serialize_model(self, instance): + def serialize_model(self, instance, request=None): """ Given a model instance or dict, serialize it to a dict.. """ @@ -244,8 +244,8 @@ class Serializer(object): continue try: - key = self.serialize_key(fname) - val = self.serialize_val(fname, obj) + key = self.serialize_key(fname, request) + val = self.serialize_val(fname, obj, request) data[key] = val except _SkipField: pass @@ -253,54 +253,54 @@ class Serializer(object): return data - def serialize_iter(self, obj): + def serialize_iter(self, obj, request=None): """ Convert iterables into a serializable representation. """ - return [self.serialize(item) for item in obj] + return [self.serialize(item, request) for item in obj] - def serialize_func(self, obj): + def serialize_func(self, obj, request=None): """ Convert no-arg methods and functions into a serializable representation. """ - return self.serialize(obj()) + return self.serialize(obj(), request) - def serialize_manager(self, obj): + def serialize_manager(self, obj, request=None): """ Convert a model manager into a serializable representation. """ - return self.serialize_iter(obj.all()) + return self.serialize_iter(obj.all(), request) - def serialize_fallback(self, obj): + def serialize_fallback(self, obj, request=None): """ Convert any unhandled object into a serializable representation. """ return smart_unicode(obj, strings_only=True) - def serialize(self, obj): + def serialize(self, obj, request=None): """ Convert any object into a serializable representation. """ if isinstance(obj, (dict, models.Model)): # Model instances & dictionaries - return self.serialize_model(obj) + return self.serialize_model(obj, request) elif isinstance(obj, (tuple, list, set, QuerySet, types.GeneratorType)): # basic iterables - return self.serialize_iter(obj) + return self.serialize_iter(obj, request) elif isinstance(obj, models.Manager): # Manager objects - return self.serialize_manager(obj) + return self.serialize_manager(obj, request) elif inspect.isfunction(obj) and not inspect.getargspec(obj)[0]: # function with no args - return self.serialize_func(obj) + return self.serialize_func(obj, request) elif inspect.ismethod(obj) and len(inspect.getargspec(obj)[0]) <= 1: # bound method - return self.serialize_func(obj) + return self.serialize_func(obj, request) # Protected types are passed through as is. # (i.e. Primitives like None, numbers, dates, and Decimals.) @@ -308,4 +308,4 @@ class Serializer(object): return obj # All other values are converted to string. - return self.serialize_fallback(obj) + return self.serialize_fallback(obj, request) diff --git a/djangorestframework/views.py b/djangorestframework/views.py index 5f8e84cd2..afd81b3fa 100644 --- a/djangorestframework/views.py +++ b/djangorestframework/views.py @@ -141,7 +141,7 @@ class View(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, DjangoView): response = Response(status.HTTP_204_NO_CONTENT) # Pre-serialize filtering (eg filter complex objects into natively serializable types) - response.cleaned_content = self.filter_response(response.raw_content) + response.cleaned_content = self.filter_response(response.raw_content, request) except ErrorResponse, exc: response = exc.response