mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-09-21 03:19:00 +03:00
Add support for field_classes on ModelSerializer
This commit is contained in:
parent
04e0c2b9ab
commit
7f02a813af
|
@ -527,6 +527,21 @@ You can add extra fields to a `ModelSerializer` or override the default fields b
|
|||
|
||||
Extra fields can correspond to any property or callable on the model.
|
||||
|
||||
## Specifying field classes
|
||||
|
||||
In order to override the field class only, and still get the field kwargs set dynamically, you may use the `field_classes`
|
||||
Meta option.
|
||||
|
||||
class AccountSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Account
|
||||
fields = ['account_name']
|
||||
field_classes = {'account_name': AccountNameField}
|
||||
|
||||
Note that the field class that you use needs to support whatever kwargs the serializer determines to use for this field.
|
||||
Typically, you want your custom field class to inherit from the appropriate built in field class.
|
||||
For example, the custom `AccountNameField` could inherit from the built in `CharField`.
|
||||
|
||||
## Specifying read only fields
|
||||
|
||||
You may wish to specify multiple fields as read-only. Instead of adding each field explicitly with the `read_only=True` attribute, you may use the shortcut Meta option, `read_only_fields`.
|
||||
|
|
|
@ -1054,6 +1054,11 @@ class ModelSerializer(Serializer):
|
|||
source, info, model, depth
|
||||
)
|
||||
|
||||
# Override field_class by classes defined in `Meta.field_classes`.
|
||||
field_class = self.get_field_class(
|
||||
source, info, model, field_class
|
||||
)
|
||||
|
||||
# Include any kwargs defined in `Meta.extra_kwargs`
|
||||
field_kwargs = self.include_extra_kwargs(
|
||||
field_kwargs, extra_field_kwargs
|
||||
|
@ -1319,6 +1324,17 @@ class ModelSerializer(Serializer):
|
|||
(field_name, model_class.__name__)
|
||||
)
|
||||
|
||||
def get_field_class(self, field_name, info, model_class, field_class):
|
||||
"""
|
||||
Get field class from 'field_classes', or use the default.
|
||||
"""
|
||||
field_classes = getattr(self.Meta, 'field_classes', {})
|
||||
|
||||
if field_name in field_classes:
|
||||
return field_classes[field_name]
|
||||
|
||||
return field_class
|
||||
|
||||
def include_extra_kwargs(self, kwargs, extra_kwargs):
|
||||
"""
|
||||
Include any 'extra_kwargs' that have been included for this field,
|
||||
|
|
|
@ -271,6 +271,26 @@ class TestRegularFieldMappings(TestCase):
|
|||
""")
|
||||
self.assertEqual(repr(TestSerializer()), expected)
|
||||
|
||||
def test_field_classes(self):
|
||||
"""
|
||||
Ensure `field_classes` do override the field class.
|
||||
"""
|
||||
class CustomCharField(serializers.CharField):
|
||||
pass
|
||||
|
||||
class TestSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = RegularFieldsModel
|
||||
fields = ('auto_field', 'char_field')
|
||||
field_classes = {'char_field': CustomCharField}
|
||||
|
||||
expected = dedent("""
|
||||
TestSerializer():
|
||||
auto_field = IntegerField(read_only=True)
|
||||
char_field = CustomCharField(max_length=100)
|
||||
""")
|
||||
self.assertEqual(repr(TestSerializer()), expected)
|
||||
|
||||
def test_extra_field_kwargs(self):
|
||||
"""
|
||||
Ensure `extra_kwargs` are passed to generated fields.
|
||||
|
|
Loading…
Reference in New Issue
Block a user