Question:
How can I access the serializer instance or any relevant arguments in the default callable function of DRF field?
Scenario:
I have a serializer configuration as below,
JavaScript
x
7
1
def bar_value_callable_function(serializer_instance):
2
if serializer_instance.context['request'].method == 'GET':
3
return 'return value One'
4
return 'return value Two'
5
6
class FooSerializer(serializers.Serializer):
7
bar = serializers.CharField(source='foo.bar', default=bar_value_callable_function)
JavaScript
1
3
1
serializer = FooSerializer(foo_instance, context={'request': request})
2
print(serializer.data)
3
I am gettting error as,
JavaScript
1
2
1
TypeError: bar_value_callable_function() missing 1 required positional argument: 'serializer_instance'
2
Advertisement
Answer
Update
For DRF>=3.12, use this king of default class
JavaScript
1
7
1
class DefaultBarValue:
2
requires_context = True
3
4
def __call__(self, serializer_instance):
5
if serializer_instance.context['request'].method == 'GET':
6
return 'return value One'
7
return 'return value Two'
pass a class instance instead of function to the default
argument
JavaScript
1
23
23
1
# default callable class
2
class DefaultBarValue:
3
"""
4
"Method `set_context` on defaults is deprecated and will
5
no longer be called starting with 3.12. Instead set
6
`requires_context = True` on the class, and accept the
7
context as an additional argument.
8
"""
9
requires_context = True # for DRF>=3.12
10
serializer_instance = None # not required for DRF>=3.12
11
12
def set_context(self, serializer_instance): # not required for DRF>=3.12
13
self.serializer_instance = serializer_instance
14
15
def __call__(self, serializer_instance=None):
16
if serializer_instance is None: # will be None for older versions of DRF
17
if self.serializer_instance.context['request'].method == 'GET':
18
return 'return value One'
19
return 'return value Two'
20
else: # for DRF>=3.12
21
if serializer_instance.context['request'].method == 'GET':
22
return 'return value One'
23
return 'return value Two'
JavaScript
1
3
1
# serializer
2
class FooSerializer(serializers.Serializer):
3
bar = serializers.CharField(source='foo.bar', default=DefaultBarValue())