1

I don't know how to add additional fields to my ModelSerializer, which accepts many=True. Here is all my code:

ViewSet:

 def list(self, request, *args, **kwargs):
    contracts = self.request.user.all_contracts
    serializer = ContractGetSerializer(contracts, many=True, context={'request': request}, )
    return Response({"results": serializer.data}, status=status.HTTP_200_OK)

ContractGetSerializer serializer. It also has inner Many=True fields

class ContractGetSerializer(serializers.ModelSerializer):
files = FileModelSerializer(many=True)
is_author = serializers.SerializerMethodField('is_author_method')
contract_signing_status = serializers.SerializerMethodField('get_recipient_signing_status')

def is_author_method(self, foo):
    return foo.owner.id == self.context['request'].user.id

class Meta:
    model = Contract
    fields = ['id', 'is_author', 'title','contract_signing_status','files', ]

Now my ContractGetSerializer returns a ReturnList with all contracts. How can I add additional fields to that ReturnList and make it a dictionary?

I need for instance to return only 5 recent contracts (filtered by timestamp). Also, I need to add total SIGNED contracts, and total PENDING contracts, counting all contracts data so that my frontend would not need to do this.

My current JSON:

    {
  "results": [
    {
      "id": 178,
      "is_author": true,
      "title": "ahhzhzh",
      "message_to_all_recipients": null,
      "contract_signing_status": "WAITING_FOR_ME",
      "contract_signing_type": "SIMPLE",
      "contract_signing_date": {
        "start_date": "2010-09-04T14:15:22Z",
        "end_date": "2010-09-04T14:15:22Z"
      },
      "recipients": [
        {
          "message": null,
          "recipient_signing_status": "NOT_SIGNED",
          "recipient_review_status": "NOT_REQUIRED",
          "recipient_action": "SIGN",
          "role": "ADMIN"
        },
        {
          "message": null,
          "recipient_signing_status": "NOT_SIGNED",
          "recipient_review_status": "NOT_REQUIRED",
          "recipient_action": "SIGN",
          "role": "BASE"
        }
      ]
    },
    {
      "id": 179,
      "is_author": true,
      "title": "dhhdhd",
      "message_to_all_recipients": null,
      "contract_signing_status": "WAITING_FOR_ME",
      "contract_signing_type": "SIMPLE",
      "contract_signing_date": {
        "start_date": "2010-09-04T14:15:22Z",
        "end_date": "2010-09-04T14:15:22Z"
      },
      "recipients": [
        {
          "message": null,
          "recipient_signing_status": "NOT_SIGNED",
          "recipient_review_status": "NOT_REQUIRED",
          "recipient_action": "SIGN",
          "role": "ADMIN"
        },
        {
          "message": null,
          "recipient_signing_status": "NOT_SIGNED",
          "recipient_review_status": "NOT_REQUIRED",
          "recipient_action": "SIGN",
          "role": "BASE"
        }
      ]
    },
 
  ]
}

My desired JSON:

{
  "recents_count": 5,
  "signed_count": 10,
  "results": [
    {
      "id": 178,
      "is_author": true,
      "title": "ahhzhzh",
      "message_to_all_recipients": null,
      "contract_signing_status": "WAITING_FOR_ME",
      "contract_signing_type": "SIMPLE",
      "contract_signing_date": {
        "start_date": "2010-09-04T14:15:22Z",
        "end_date": "2010-09-04T14:15:22Z"
      },
      "recipients": [
        {
          "message": null,
          "recipient_signing_status": "NOT_SIGNED",
          "recipient_review_status": "NOT_REQUIRED",
          "recipient_action": "SIGN",
          "role": "ADMIN"
        },
        {
          "message": null,
          "recipient_signing_status": "NOT_SIGNED",
          "recipient_review_status": "NOT_REQUIRED",
          "recipient_action": "SIGN",
          "role": "BASE"
        }
      ]
    },
    {
      "id": 179,
      "is_author": true,
      "title": "dhhdhd",
      "message_to_all_recipients": null,
      "contract_signing_status": "WAITING_FOR_ME",
      "contract_signing_type": "SIMPLE",
      "contract_signing_date": {
        "start_date": "2010-09-04T14:15:22Z",
        "end_date": "2010-09-04T14:15:22Z"
      },
      "recipients": [
        {
          "message": null,
          "recipient_signing_status": "NOT_SIGNED",
          "recipient_review_status": "NOT_REQUIRED",
          "recipient_action": "SIGN",
          "role": "ADMIN"
        },
        {
          "message": null,
          "recipient_signing_status": "NOT_SIGNED",
          "recipient_review_status": "NOT_REQUIRED",
          "recipient_action": "SIGN",
          "role": "BASE"
        }
      ]
    },
 
  ]
}
2
  • can you add your desired JSON response example to the question so everyone can give you a good answer Commented Mar 20, 2021 at 21:59
  • added. you can check it Commented Mar 20, 2021 at 22:33

1 Answer 1

2

There are multiple ways to do so, but I think doing this in serializers is better.

I will do something like this:

at view

def list(self, request, *args, **kwargs):
    serializer = ContractResultSerializer(self.request.user, context={'request': request}, )
    return Response(serializer.data, status=status.HTTP_200_OK)

at serializers

class ContractResultSerializer(serializers.Serializer):
    recents_count = serializers.SerializerMethodField()
    signed_count = serializers.SerializerMethodField()
    results = serializers.SerializerMethodField()

    def get_recents_count(self, obj):
        # I don't know what your model looks like to write the query to get the recent count
        # but I think it will be something like this 
        return obj.contracts.filter(your recent condition).count()

    def get_signed_count(self, obj):
       # is the same as get_recents_count()

    def get_results(self, obj):
        return ContractGetSerializer(obj.all_contracts, many=True, context={'request': self.context['request']}).data

class ContractGetSerializer(serializers.ModelSerializer):
    files = FileModelSerializer(many=True)
    is_author = serializers.SerializerMethodField('is_author_method')
    contract_signing_status = serializers.SerializerMethodField('get_recipient_signing_status')

    def is_author_method(self, foo):
        return foo.owner.id == self.context['request'].user.id

    class Meta:
        model = Contract
        fields = ['id', 'is_author', 'title','contract_signing_status','files', ]

You can also do the same if you like in your view instead of writing a new serializer for ex:

def list(self, request, *args, **kwargs):
    contracts = self.request.user.all_contracts
    serializer = ContractGetSerializer(contracts, many=True, context={'request': request}, )
    response ={
         "recents_count": self.request.user.contracts.filter(your recent condition).count(),
         "signed_count": self.request.user.contracts.filter(your recent condition).count(),
         "results": serializer.data
    }
    return Response(response, status=status.HTTP_200_OK)
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks! Very good explanation. Somehow, I got only a single contract not the list of the contracts in my ContractResultSerializer, but I think I will solve it myself from now on! Also, by the way, can you look at my other question? stackoverflow.com/questions/66726368/…
Good to hear that. sorry for the late reply, I will check this other question now.
it's serializers.Serializer without the s

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.