I have a Django REST Framework serializer that is used in several places. One of the fields is a SerializerMethodField that I only wanted to include if the serializer is used to serialize only a single object. Basically, I want to not include one of the SerializerMethodField (or change it's behavior) when I have that MySerializer(objects, many=True)
. Any ideas how to do this?
Asked
Active
Viewed 850 times
1

AKX
- 152,115
- 15
- 115
- 172

Iga Quintana
- 129
- 3
- 7
-
Does this answer your question? [Django rest framework, use different serializers in the same ModelViewSet](https://stackoverflow.com/questions/22616973/django-rest-framework-use-different-serializers-in-the-same-modelviewset) – Dušan Maďar Sep 07 '20 at 06:37
-
@DušanMaďar That can work but requires to write a separate serializer. Just wondering if there's a solution to use the same one. – Iga Quintana Sep 07 '20 at 06:41
-
1You could just subclass from `MySerializer` to be e.g. `MyListSerializer`; you can also subclass `MySerializer.Meta` within your new `MyListSerializer` and e.g. remove entries from `fields`. – AKX Sep 07 '20 at 06:49
2 Answers
2
Hi here is my solution to determine if we are in context of many=True: I override the new class method and add a "has_many" key to the context kwargs object:
class MySerializer(serializer.ModelSerializer):
def __new__(cls, *args, **kwargs):
if kwargs.get('many', False) is True:
context = kwargs.get('context', {})
context.update({'has_many': True})
kwargs.update({'context': context})
return super().__new__(cls, *args, **kwargs)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if self.context.get('has_many', False):
# Do something
1
One easy way to dynamically remove fields from your serializer is to add following codes to your serializer:
class MySerializer(serializer.ModelSerializer):
def __init__(self, *args, **kwargs):
remove_fields = kwargs.pop('remove_fields', None)
super(MySerializer, self).__init__(*args, **kwargs)
if remove_fields:
# for multiple fields in a list
for field_name in remove_fields:
self.fields.pop(field_name, None)
And then when you need to remove some fields from your serializer is to use MySerializer(objects, many=True, remove_fields=['list_of_your_fields',])
which will remove list_of_your_fields
' fields from your output data

Roham
- 1,970
- 2
- 6
- 16