Set this to True to ensure that the field is used when serializing a representation, but is not used when creating or updating an instance during deserialization.
Set this to True to ensure that the field may be used when updating or creating an instance, but is not included when serializing the representation.
Setting this to False also allows the object attribute or dictionary key to be omitted from output when serializing the instance.
default If set, this gives the default value that will be used for the field if no input value is supplied.
Normally an error will be raised if None is passed to a serializer field. Set this keyword argument to True if None should be considered a valid value.
The name of the attribute that will be used to populate the field.
A list of validator functions which should be applied to the incoming field input, and which either raise a validation error or simply return.
A dictionary of error codes to error messages.
A short text string that may be used as the name of the field in HTML form fields or other descriptive elements.
A text string that may be used as a description of the field in HTML form fields or other descriptive elements.
A value that should be used for pre-populating the value of HTML form fields.
Above information is from GeeksforGeeks.
Arguments
Syntax
field_name = serializers.ListField(*args, **kwargs)
Example
scores = serializers.ListField(
child=serializers.IntegerField(min_value=0, max_value=100)
)
// Create a dictionary and add invalid values
>>> data = {}
>>> data['integers'] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
// dictionary created
>>> data
{'integers': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]}
// deserialize the data
>>> serializer = GeeksSerializer(data=data)
// check if data is valid
>>> serializer.is_valid()
True
// print the data
>>> serializer.data
{'integers': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]}
// check the errors
>>> serializer.errors
{}
context
required=True
For nested relationships
partial=True
updating only partial information
source
ModelSerializer Fields
By default, all the model fields on the class will be mapped to a corresponding serializer fields.
Any relationships such as foreign keys on the model will be mapped to PrimaryKeyRelatedField. Reverse relationships are not included by default unless explicitly included as specified in the serializer relations documentation.
The names in the fields and exclude attributes will normally map to model fields on the model class.
Alternatively names in the fields options can map to properties or methods which take no arguments that exist on the model class.
Since version 3.3.0, it is mandatory to provide one of the attributes fields or exclude.
urlpatterns = [
...
url(r'^api/topic_detail/(?P<name>[a-zA-Z0-9-]+)/content_list/$', views.topic_content_list, name='topic_content_list'),
...
]
For instance, if you would like to modify the automatic lookup parameter of your router from pk to uuid:
class ProductViewSet(ModelViewSet):
lookup_field = 'my_uuid_field'
lookup_field
tells DRF to use this field instead of pk
to get items.
If you would like to use different serializer classes for different HTTP request in a same ModelViewSet, override the get_serializer_class()
method.
class DualSerializerViewSet(viewsets.ModelViewSet):
def get_serializer_class(self):
if self.action == 'list':
return serializers.ListaGruppi
if self.action == 'retrieve':
return serializers.DettaglioGruppi
return serializers.Default
If this throws an exception, try if hasattr(self, 'action') and self.action == 'list'
. (Django rest swagger does not place a self.action parameter, so the function above may throw an exception.
Or, use the mixin below:
class MultiSerializerViewSetMixin(object):
def get_serializer_class(self):
/*
Look for serializer class in self.serializer_action_classes, which
should be a dict mapping action name (key) to serializer class (value),
i.e.:
class MyViewSet(MultiSerializerViewSetMixin, ViewSet):
serializer_class = MyDefaultSerializer
serializer_action_classes = {
'list': MyListSerializer,
'my_action': MyActionSerializer,
}
@action
def my_action:
...
If there's no entry for that action then just fallback to the regular
get_serializer_class lookup: self.serializer_class, DefaultSerializer.
*/
try:
return self.serializer_action_classes[self.action]
except (KeyError, AttributeError):
return super(MultiSerializerViewSetMixin, self).get_serializer_class()
class MySerializer(serializers.ModelSerializer):
write_only_char_field = serializers.CharField(write_only=True)
write_only_list_char_field = serializers.ListField(child=serializers.CharField(max_length=100, default=''), write_only=True)
empty_method_field = serializers.SerializerMethodField()
read_only_custom_model_field = serializers.CharField(source='custom_property', read_only=True)
def create(self, validated_data):
validated_data.pop('write_only_char_field', None)
validated_data.pop('write_only_list_char_field', None)
return super().create(validated_data)
The read_only_custom_model_field
would use a method on your model to read some data, not strictly a model field, but a custom method. I.e.
class MyModel(models.Model):
my_field = models.CharField(max_length=100)
@property
def custom_property(self):
return "Perform calculations, combine with related models, etc. etc."
Use SerializerMethodField
.
class ResearchSerializer(serializers.ModelSerializer):
templates = serializers.SerializerMethodField()
class Meta:
model = Research
fields = ('id', 'created', 'speaker', 'body', 'templates')
def get_templates(self, obj):
values = obj.get_values() # whatever your filter values are. obj is the Research instance
templates = ResearchTemplate.objects.filter(mergefields__contained_by=values) # Or whatever queryset filter
return ResearchTemplateSerializer(templates, many=True).data
Use DynamicFieldsModelSerializer
class DynamicFieldsModelSerializer(serializers.ModelSerializer):
def __init__(self, *args, **kwargs):
# Instantiate the superclass normally
super(DynamicFieldsModelSerializer, self).__init__(*args, **kwargs)
fields = self.context['request'].query_params.get('fields')
if fields:
fields = fields.split(',')
# Drop any fields that are not specified in the 'fields' argument
allowed = set(fields)
existing = set(self.fields.keys())
for field_name in existing - allowed:
self.fields.pop(field_name)
Article on how to customize our response based on request parameters