mirror of
				https://github.com/encode/django-rest-framework.git
				synced 2025-11-04 18:08:03 +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