I am trying to initialize a django model's object inside a Serializer class. Lets say I have 2 models ABCD and WXYZ. I performed a filter on ABCD and send the results to a serializer. The serializer need to get an instance of WXYZ model using a field of ABCD model, and fetch some result. I want to get the WXYZ instance in the init method, so that I can access that across all functions in the serializer class. Models:
class ABCD():
col1 = models.Integerfield(...)
...
class WXYZ():
col2 = models.Integerfield(...)
title = models.Charfield(...)
...
views.py:
# performed a filter on ABCD model
abcd_objects = ABCD.objects.filter(...)
results = ABCDserializer(abcd_objects, many=True).data
serialzers.py
class ABCDserializer(serializers.ModelSerializer):
title = serializers.SerializerMethodField('fetch_title')
...
def __init__(self, obj):
ans = WXYX.objects.get(col2=obj.col1)
self.wxyz_obj = ans
def fetch_title(self, obj):
return self.wxyz_obj.title
class Meta:
model = ABCD
fields = ['title', ...]
CodePudding user response:
Don't override the __init__
of the serializer; look up the related wxyz in e.g. a property using self.instance
.
class ABCDserializer(serializers.ModelSerializer):
title = serializers.SerializerMethodField("fetch_title")
# TODO: Use `functools.cached_property` if on Python 3.8
@property
def _related_wxyz(self):
return WXYZ.objects.get(col2=self.instance.col1)
def fetch_title(self, obj):
return self._related_wxyz.title
class Meta:
model = ABCD
fields = ["title", ...]
(This will need to make N extra queries, of course; if that is a problem, you could optimize this by prefetching the WXYZes for each ABCD so the serializer doesn't need to, but that's more involved and really a separate question.)