1+ import warnings
2+
13import inflection
24from django .core .exceptions import ObjectDoesNotExist
35from django .db .models .query import QuerySet
1517 get_resource_type_from_serializer
1618)
1719
20+ from rest_framework_json_api .settings import json_api_settings
21+
1822
1923class ResourceIdentifierObjectSerializer (BaseSerializer ):
2024 default_error_messages = {
@@ -115,8 +119,41 @@ def validate_path(serializer_class, field_path, path):
115119 super (IncludedResourcesValidationMixin , self ).__init__ (* args , ** kwargs )
116120
117121
122+ class SerializerMetaclass (SerializerMetaclass ):
123+
124+ @classmethod
125+ def _get_declared_fields (cls , bases , attrs ):
126+ fields = super ()._get_declared_fields (bases , attrs )
127+ for field_name , field in fields .items ():
128+ if isinstance (field , BaseSerializer ) and \
129+ not json_api_settings .SERIALIZE_NESTED_SERIALIZERS_AS_ATTRIBUTE :
130+ clazz = '{}.{}' .format (attrs ['__module__' ], attrs ['__qualname__' ])
131+ if isinstance (field , ListSerializer ):
132+ nested_class = type (field .child ).__name__
133+ else :
134+ nested_class = type (field ).__name__
135+
136+ warnings .warn (DeprecationWarning (
137+ "Rendering nested serializer as relationship is deprecated. "
138+ "Use `ResourceRelatedField` instead if {} in serializer {} should remain "
139+ "a relationship. Otherwise set "
140+ "JSON_API_SERIALIZE_NESTED_SERIALIZERS_AS_ATTRIBUTE to True to render nested "
141+ "serializer as nested json attribute" .format (nested_class , clazz )))
142+ return fields
143+
144+
145+ # If user imports serializer from here we can catch class definition and check
146+ # nested serializers for depricated use.
147+ class Serializer (
148+ IncludedResourcesValidationMixin , SparseFieldsetsMixin , Serializer ,
149+ metaclass = SerializerMetaclass
150+ ):
151+ pass
152+
153+
118154class HyperlinkedModelSerializer (
119- IncludedResourcesValidationMixin , SparseFieldsetsMixin , HyperlinkedModelSerializer
155+ IncludedResourcesValidationMixin , SparseFieldsetsMixin , HyperlinkedModelSerializer ,
156+ metaclass = SerializerMetaclass
120157):
121158 """
122159 A type of `ModelSerializer` that uses hyperlinked relationships instead
@@ -132,7 +169,8 @@ class HyperlinkedModelSerializer(
132169 """
133170
134171
135- class ModelSerializer (IncludedResourcesValidationMixin , SparseFieldsetsMixin , ModelSerializer ):
172+ class ModelSerializer (IncludedResourcesValidationMixin , SparseFieldsetsMixin , ModelSerializer ,
173+ metaclass = SerializerMetaclass ):
136174 """
137175 A `ModelSerializer` is just a regular `Serializer`, except that:
138176
@@ -193,9 +231,11 @@ def to_representation(self, instance):
193231 def _get_field_representation (self , field , instance ):
194232 request = self .context .get ('request' )
195233 is_included = field .source in get_included_resources (request )
234+ render_nested_as_attribute = json_api_settings .SERIALIZE_NESTED_SERIALIZERS_AS_ATTRIBUTE
196235 if not is_included and \
197236 isinstance (field , ModelSerializer ) and \
198- hasattr (instance , field .source + '_id' ):
237+ hasattr (instance , field .source + '_id' ) and \
238+ not render_nested_as_attribute :
199239 attribute = getattr (instance , field .source + '_id' )
200240
201241 if attribute is None :
0 commit comments