Home > front end >  Django REST Framework Serializer Initialize variable in init
Django REST Framework Serializer Initialize variable in init

Time:01-28

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.)

  •  Tags:  
  • Related