mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-07-27 08:29:59 +03:00
add write_only_fields option to model serializer extra kwargs
This commit is contained in:
parent
e5fb9af0ea
commit
729b6ca188
|
@ -77,6 +77,13 @@ LIST_SERIALIZER_KWARGS = (
|
|||
|
||||
ALL_FIELDS = '__all__'
|
||||
|
||||
READ_ONLY_FIELDS = 'read_only_fields'
|
||||
WRITE_ONLY_FIELDS = 'write_only_fields'
|
||||
EXTRA_KWARGS_FIELDS = {
|
||||
READ_ONLY_FIELDS: 'read_only',
|
||||
WRITE_ONLY_FIELDS: 'write_only',
|
||||
}
|
||||
|
||||
|
||||
# BaseSerializer
|
||||
# --------------
|
||||
|
@ -1373,26 +1380,27 @@ class ModelSerializer(Serializer):
|
|||
"""
|
||||
extra_kwargs = copy.deepcopy(getattr(self.Meta, 'extra_kwargs', {}))
|
||||
|
||||
read_only_fields = getattr(self.Meta, 'read_only_fields', None)
|
||||
if read_only_fields is not None:
|
||||
if not isinstance(read_only_fields, (list, tuple)):
|
||||
raise TypeError(
|
||||
'The `read_only_fields` option must be a list or tuple. '
|
||||
'Got %s.' % type(read_only_fields).__name__
|
||||
)
|
||||
for field_name in read_only_fields:
|
||||
kwargs = extra_kwargs.get(field_name, {})
|
||||
kwargs['read_only'] = True
|
||||
extra_kwargs[field_name] = kwargs
|
||||
for option, limit in EXTRA_KWARGS_FIELDS.items():
|
||||
fields = getattr(self.Meta, option, None)
|
||||
|
||||
else:
|
||||
# Guard against the possible misspelling `readonly_fields` (used
|
||||
# by the Django admin and others).
|
||||
assert not hasattr(self.Meta, 'readonly_fields'), (
|
||||
'Serializer `%s.%s` has field `readonly_fields`; '
|
||||
'the correct spelling for the option is `read_only_fields`.' %
|
||||
(self.__class__.__module__, self.__class__.__name__)
|
||||
)
|
||||
if fields is not None:
|
||||
if not isinstance(fields, (list, tuple)):
|
||||
raise TypeError(
|
||||
f'The `{option}` option must be a list or tuple. '
|
||||
f'Got {type(fields).__name__}.'
|
||||
)
|
||||
for field_name in fields:
|
||||
kwargs = extra_kwargs.get(field_name, {})
|
||||
kwargs[limit] = True
|
||||
extra_kwargs[field_name] = kwargs
|
||||
else:
|
||||
# Guard against the possible misspelling `readonly_fields` (used
|
||||
# by the Django admin and others).
|
||||
assert not hasattr(self.Meta, 'readonly_fields'), (
|
||||
'Serializer `%s.%s` has field `readonly_fields`; '
|
||||
'the correct spelling for the option is `read_only_fields`.' %
|
||||
(self.__class__.__module__, self.__class__.__name__)
|
||||
)
|
||||
|
||||
return extra_kwargs
|
||||
|
||||
|
|
|
@ -47,6 +47,11 @@ class OneFieldModel(models.Model):
|
|||
char_field = models.CharField(max_length=100)
|
||||
|
||||
|
||||
class TwoFieldModel(models.Model):
|
||||
char_field = models.CharField(max_length=100)
|
||||
datetime_field = models.DateTimeField()
|
||||
|
||||
|
||||
class RegularFieldsModel(models.Model):
|
||||
"""
|
||||
A model class for testing regular flat fields.
|
||||
|
@ -1078,25 +1083,29 @@ class TestMetaInheritance(TestCase):
|
|||
non_model_field = serializers.CharField()
|
||||
|
||||
class Meta:
|
||||
model = OneFieldModel
|
||||
model = TwoFieldModel
|
||||
read_only_fields = ('char_field', 'non_model_field')
|
||||
fields = read_only_fields
|
||||
write_only_fields = ('datetime_field',)
|
||||
fields = read_only_fields + write_only_fields
|
||||
extra_kwargs = {}
|
||||
|
||||
class ChildSerializer(TestSerializer):
|
||||
class Meta(TestSerializer.Meta):
|
||||
read_only_fields = ()
|
||||
write_only_fields = ()
|
||||
|
||||
test_expected = dedent("""
|
||||
TestSerializer():
|
||||
char_field = CharField(read_only=True)
|
||||
non_model_field = CharField()
|
||||
datetime_field = DateTimeField(write_only=True)
|
||||
""")
|
||||
|
||||
child_expected = dedent("""
|
||||
ChildSerializer():
|
||||
char_field = CharField(max_length=100)
|
||||
non_model_field = CharField()
|
||||
datetime_field = DateTimeField()
|
||||
""")
|
||||
self.assertEqual(repr(ChildSerializer()), child_expected)
|
||||
self.assertEqual(repr(TestSerializer()), test_expected)
|
||||
|
@ -1124,6 +1133,27 @@ class TestModelFieldValues(TestCase):
|
|||
self.assertEqual(serializer.data, {'target': 1})
|
||||
|
||||
|
||||
class TestExtraKwargs(TestCase):
|
||||
def test_write_only_fields(self):
|
||||
class TestSerializer(serializers.ModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = OneFieldModel
|
||||
write_only_fields = ('char_field',)
|
||||
fields = write_only_fields
|
||||
|
||||
test_expected = dedent("""
|
||||
TestSerializer():
|
||||
char_field = CharField(max_length=100, write_only=True)
|
||||
""")
|
||||
|
||||
self.assertEqual(repr(TestSerializer()), test_expected)
|
||||
self.assertEqual(
|
||||
TestSerializer().get_extra_kwargs().get('char_field', {}).get('write_only'),
|
||||
True,
|
||||
)
|
||||
|
||||
|
||||
class TestUniquenessOverride(TestCase):
|
||||
def test_required_not_overwritten(self):
|
||||
class TestModel(models.Model):
|
||||
|
|
Loading…
Reference in New Issue
Block a user