@@ -883,41 +883,14 @@ def get_fields(self):
883
883
884
884
ret = OrderedDict ()
885
885
model = getattr (self .Meta , 'model' )
886
- fields = getattr (self .Meta , 'fields' , None )
887
- exclude = getattr (self .Meta , 'exclude' , None )
888
886
depth = getattr (self .Meta , 'depth' , 0 )
889
887
extra_kwargs = getattr (self .Meta , 'extra_kwargs' , {})
890
-
891
- if fields and not isinstance (fields , (list , tuple )):
892
- raise TypeError (
893
- 'The `fields` option must be a list or tuple. Got %s.' %
894
- type (fields ).__name__
895
- )
896
-
897
- if exclude and not isinstance (exclude , (list , tuple )):
898
- raise TypeError (
899
- 'The `exclude` option must be a list or tuple. Got %s.' %
900
- type (exclude ).__name__
901
- )
902
-
903
- assert not (fields and exclude ), "Cannot set both 'fields' and 'exclude'."
904
-
905
888
extra_kwargs = self ._include_additional_options (extra_kwargs )
906
889
907
890
# Retrieve metadata about fields & relationships on the model class.
908
891
info = model_meta .get_field_info (model )
909
892
910
- # Use the default set of field names if none is supplied explicitly.
911
- if fields is None :
912
- fields = self ._get_default_field_names (declared_fields , info )
913
- exclude = getattr (self .Meta , 'exclude' , None )
914
- if exclude is not None :
915
- for field_name in exclude :
916
- assert field_name in fields , (
917
- 'The field in the `exclude` option must be a model field. Got %s.' %
918
- field_name
919
- )
920
- fields .remove (field_name )
893
+ fields = self .get_field_names (declared_fields , info )
921
894
922
895
# Determine the set of model fields, and the fields that they map to.
923
896
# We actually only need this to deal with the slightly awkward case
@@ -1133,7 +1106,72 @@ def _include_additional_options(self, extra_kwargs):
1133
1106
1134
1107
return extra_kwargs
1135
1108
1136
- def _get_default_field_names (self , declared_fields , model_info ):
1109
+ def get_field_names (self , declared_fields , info ):
1110
+ """
1111
+ Returns the list of all field names that should be created when
1112
+ instantiating this serializer class. This is based on the default
1113
+ set of fields, but also takes into account the `Meta.fields` or
1114
+ `Meta.exclude` options if they have been specified.
1115
+ """
1116
+ fields = getattr (self .Meta , 'fields' , None )
1117
+ exclude = getattr (self .Meta , 'exclude' , None )
1118
+
1119
+ if fields and not isinstance (fields , (list , tuple )):
1120
+ raise TypeError (
1121
+ 'The `fields` option must be a list or tuple. Got %s.' %
1122
+ type (fields ).__name__
1123
+ )
1124
+
1125
+ if exclude and not isinstance (exclude , (list , tuple )):
1126
+ raise TypeError (
1127
+ 'The `exclude` option must be a list or tuple. Got %s.' %
1128
+ type (exclude ).__name__
1129
+ )
1130
+
1131
+ assert not (fields and exclude ), (
1132
+ "Cannot set both 'fields' and 'exclude' options on "
1133
+ "serializer {serializer_class}." .format (
1134
+ serializer_class = self .__class__ .__name__
1135
+ )
1136
+ )
1137
+
1138
+ if fields is not None :
1139
+ # Ensure that all declared fields have also been included in the
1140
+ # `Meta.fields` option.
1141
+ for field_name in declared_fields :
1142
+ assert field_name in fields , (
1143
+ "The field '{field_name}' was declared on serializer "
1144
+ "{serializer_class}, but has not been included in the "
1145
+ "'fields' option." .format (
1146
+ field_name = field_name ,
1147
+ serializer_class = self .__class__ .__name__
1148
+ )
1149
+ )
1150
+ return fields
1151
+
1152
+ # Use the default set of field names if `Meta.fields` is not specified.
1153
+ fields = self .get_default_field_names (declared_fields , info )
1154
+
1155
+ if exclude is not None :
1156
+ # If `Meta.exclude` is included, then remove those fields.
1157
+ for field_name in exclude :
1158
+ assert field_name in fields , (
1159
+ "The field '{field_name}' was include on serializer "
1160
+ "{serializer_class} in the 'exclude' option, but does "
1161
+ "not match any model field." .format (
1162
+ field_name = field_name ,
1163
+ serializer_class = self .__class__ .__name__
1164
+ )
1165
+ )
1166
+ fields .remove (field_name )
1167
+
1168
+ return fields
1169
+
1170
+ def get_default_field_names (self , declared_fields , model_info ):
1171
+ """
1172
+ Return the default list of field names that will be used if the
1173
+ `Meta.fields` option is not specified.
1174
+ """
1137
1175
return (
1138
1176
[model_info .pk .name ] +
1139
1177
list (declared_fields .keys ()) +
@@ -1160,7 +1198,11 @@ class HyperlinkedModelSerializer(ModelSerializer):
1160
1198
"""
1161
1199
_related_class = HyperlinkedRelatedField
1162
1200
1163
- def _get_default_field_names (self , declared_fields , model_info ):
1201
+ def get_default_field_names (self , declared_fields , model_info ):
1202
+ """
1203
+ Return the default list of field names that will be used if the
1204
+ `Meta.fields` option is not specified.
1205
+ """
1164
1206
return (
1165
1207
[api_settings .URL_FIELD_NAME ] +
1166
1208
list (declared_fields .keys ()) +
0 commit comments