1
+ import warnings
2
+
1
3
import inflection
2
4
from django .core .exceptions import ObjectDoesNotExist
3
5
from django .db .models .query import QuerySet
15
17
get_resource_type_from_serializer
16
18
)
17
19
20
+ from rest_framework_json_api .settings import json_api_settings
21
+
18
22
19
23
class ResourceIdentifierObjectSerializer (BaseSerializer ):
20
24
default_error_messages = {
@@ -115,8 +119,41 @@ def validate_path(serializer_class, field_path, path):
115
119
super (IncludedResourcesValidationMixin , self ).__init__ (* args , ** kwargs )
116
120
117
121
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
+
118
154
class HyperlinkedModelSerializer (
119
- IncludedResourcesValidationMixin , SparseFieldsetsMixin , HyperlinkedModelSerializer
155
+ IncludedResourcesValidationMixin , SparseFieldsetsMixin , HyperlinkedModelSerializer ,
156
+ metaclass = SerializerMetaclass
120
157
):
121
158
"""
122
159
A type of `ModelSerializer` that uses hyperlinked relationships instead
@@ -132,7 +169,8 @@ class HyperlinkedModelSerializer(
132
169
"""
133
170
134
171
135
- class ModelSerializer (IncludedResourcesValidationMixin , SparseFieldsetsMixin , ModelSerializer ):
172
+ class ModelSerializer (IncludedResourcesValidationMixin , SparseFieldsetsMixin , ModelSerializer ,
173
+ metaclass = SerializerMetaclass ):
136
174
"""
137
175
A `ModelSerializer` is just a regular `Serializer`, except that:
138
176
@@ -193,9 +231,11 @@ def to_representation(self, instance):
193
231
def _get_field_representation (self , field , instance ):
194
232
request = self .context .get ('request' )
195
233
is_included = field .source in get_included_resources (request )
234
+ render_nested_as_attribute = json_api_settings .SERIALIZE_NESTED_SERIALIZERS_AS_ATTRIBUTE
196
235
if not is_included and \
197
236
isinstance (field , ModelSerializer ) and \
198
- hasattr (instance , field .source + '_id' ):
237
+ hasattr (instance , field .source + '_id' ) and \
238
+ not render_nested_as_attribute :
199
239
attribute = getattr (instance , field .source + '_id' )
200
240
201
241
if attribute is None :
0 commit comments