Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6d907cd

Browse files
get_field_names, get_default_field_names
1 parent ba753a7 commit 6d907cd

File tree

2 files changed

+76
-34
lines changed

2 files changed

+76
-34
lines changed

rest_framework/serializers.py

Lines changed: 72 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -883,41 +883,14 @@ def get_fields(self):
883883

884884
ret = OrderedDict()
885885
model = getattr(self.Meta, 'model')
886-
fields = getattr(self.Meta, 'fields', None)
887-
exclude = getattr(self.Meta, 'exclude', None)
888886
depth = getattr(self.Meta, 'depth', 0)
889887
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-
905888
extra_kwargs = self._include_additional_options(extra_kwargs)
906889

907890
# Retrieve metadata about fields & relationships on the model class.
908891
info = model_meta.get_field_info(model)
909892

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)
921894

922895
# Determine the set of model fields, and the fields that they map to.
923896
# We actually only need this to deal with the slightly awkward case
@@ -1133,7 +1106,72 @@ def _include_additional_options(self, extra_kwargs):
11331106

11341107
return extra_kwargs
11351108

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+
"""
11371175
return (
11381176
[model_info.pk.name] +
11391177
list(declared_fields.keys()) +
@@ -1160,7 +1198,11 @@ class HyperlinkedModelSerializer(ModelSerializer):
11601198
"""
11611199
_related_class = HyperlinkedRelatedField
11621200

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+
"""
11641206
return (
11651207
[api_settings.URL_FIELD_NAME] +
11661208
list(declared_fields.keys()) +

tests/test_model_serializer.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -221,11 +221,11 @@ class Meta:
221221
model = RegularFieldsModel
222222
fields = ('auto_field',)
223223

224-
with self.assertRaises(ImproperlyConfigured) as excinfo:
224+
with self.assertRaises(AssertionError) as excinfo:
225225
TestSerializer().fields
226226
expected = (
227-
'Field `missing` has been declared on serializer '
228-
'`TestSerializer`, but is missing from `Meta.fields`.'
227+
"The field 'missing' was declared on serializer TestSerializer, "
228+
"but has not been included in the 'fields' option."
229229
)
230230
assert str(excinfo.exception) == expected
231231

@@ -607,5 +607,5 @@ class Meta:
607607
exception = result.exception
608608
self.assertEqual(
609609
str(exception),
610-
"Cannot set both 'fields' and 'exclude'."
610+
"Cannot set both 'fields' and 'exclude' options on serializer ExampleSerializer."
611611
)

0 commit comments

Comments
 (0)