[Django]-In a Django serializer, take default field value from context (or request data)

5👍

✅

SerializerMethodField is a read-only field so I do not think it will work unless you set a default value… and you are back to the same problem as with CharField.

To simply things you could get rid of serializers.CreateOnlyDefault:

class RRsetSerializer(serializers.ModelSerializer):
    type = serializers.CharField(read_only=True, default=TypeDefault())

If you want something more dynamic, I can only think of something like this:

class FromContext(object):
    def __init__(self, value_fn):
        self.value_fn = value_fn

    def set_context(self, serializer_field):
        self.value = self.value_fn(serializer_field.context)

    def __call__(self):
        return self.value


class RRsetSerializer(serializers.ModelSerializer):
    type = serializers.CharField(read_only=True,
            default=FromContext(lambda context: context.get('view').kwargs['type'].upper()))

FromContext takes a function during instantiation that will be used to retrieve the value you want from context.

1👍

All in all, your second approach above is the correct one:

Use serializers.SerializerMethodField and access self.context from the serializer method:

class SomeSerializer(serializers.ModelSerializer):
    type = serializers.SerializerMethodField()

    def get_type(self, obj):
        return self.context['view'].kwargs['type'].upper()

The view, request and format keys are automatically added to your serializer context by all of the DRF generic views (http://www.django-rest-framework.org/api-guide/generic-views/#methods at the end of the section). This works just fine.

If you are creating a serializer instance manually, you will have to pass context=contextDict as an argument, where contextDict is whatever you need it to be (http://www.django-rest-framework.org/api-guide/serializers/#including-extra-context).

As @Michael has pointed out in another answer, the SerializerMethodField will be read only. But going by your first example (type = serializers.CharField(read_only=True.....) this seems to be what you want.

Leave a comment