Skip to content

Instantly share code, notes, and snippets.

@mpyrev
Last active July 6, 2017 14:15
Show Gist options
  • Save mpyrev/e59919e1e9bbbe4eeec17cb0fa6ba07a to your computer and use it in GitHub Desktop.
Save mpyrev/e59919e1e9bbbe4eeec17cb0fa6ba07a to your computer and use it in GitHub Desktop.
Django REST Framework mixin making use of default values when value is None
# coding: utf-8
from __future__ import unicode_literals
from collections import OrderedDict
from rest_framework.fields import SkipField
from rest_framework.relations import PKOnlyObject
class DefaultIfNoneMixin(object):
"""
DRF doesn't use default value of serializer's field if attribute is present but None.
Mixin changes that behavior by overriding to_representation method.
Example usage:
class MySerializer(DefaultIfNoneMixin, serializers.Serializer):
a = serializers.CharField(default='default value')
"""
def to_representation(self, instance):
"""
Object instance -> Dict of primitive datatypes.
"""
ret = OrderedDict()
fields = self._readable_fields
for field in fields:
try:
attribute = field.get_attribute(instance)
except SkipField:
continue
# We skip `to_representation` for `None` values so that fields do
# not have to explicitly deal with that case.
#
# For related fields with `use_pk_only_optimization` we need to
# resolve the pk value.
check_for_none = attribute.pk if isinstance(attribute, PKOnlyObject) else attribute
if check_for_none is None:
ret[field.field_name] = None
else:
ret[field.field_name] = field.to_representation(attribute)
# The only change. Other parts are directly from DRF.
if ret[field.field_name] is None:
try:
ret[field.field_name] = field.get_default()
except SkipField:
pass
return ret
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment