Shirux
Shirux

Reputation: 153

Field Serializers Django

I have a serializer with some custom fields and those fields depends on a specific query. The problem is that each time the serializer tries to get the value for this field It must perform the query to the DB. What about if the serializer is a many=True serializer?.

class ExampleSerializer(serializers.ModelSerializer):

  field_one = serializers.SerializerMethodField()
  field_two = serializers.SerializerMethodField()
  field_three = serializers.SerializerMethodField()
  .
  .
  .

  def get_field_one(self, obj):
    try:
      # This is where i do the query
      query_result = obj.objects.filter(filter=self.context.get("filter").first()
      if query_result:
        # Do field one stuff
    except Exception:
      # Do exception stuff

  def get_field_two(self, obj):
    try:
     # This is where i do the query
     query_result = obj.objects.filter(filter=self.context.get("filter").first()
     if query_result:
        # Do field two stuff
    except Exception:
      # Do exception stuff

  def get_field_three(self, obj):
    try:
     # This is where i do the query
     query_result = obj.objects.filter(filter=self.context.get("filter").first()
     if query_result:
        # Do field three stuff
    except Exception:
      # Do exception stuff

Is there a way to store that result inside a property in the serializer? Also, if I set a value in one of the serializer field, how do I retrieve and do some maths on another field in the same serializer?

Upvotes: 2

Views: 43

Answers (1)

JPG
JPG

Reputation: 88669

If I have a choice, I would do all these calculation logic in a single method

class ExampleSerializer(serializers.ModelSerializer):
    generic_field = serializers.SerializerMethodField()

    def get_generic_field(self, obj):
        # first query
        first_result = FirstModel.objects.filter(
            filter=self.context.get("filter")
        ).aggrgate(sum=Sum('any_field'))['sum']
        # second query
        second_model_instance = SecondModel.objects.filter(
            some_value__gte=first_result).first()

        second_result = second_model_instance.some_field_name

        # and so on

        # at last, return these results as
        return {
            "first_result": first_result,
            "second_result": second_result,
            # and so on
        }

Upvotes: 1

Related Questions