如何使用 many=True 添加其他字段,例如对象计数到 ModelSerializer

How to add additional fields, like count of objects to ModelSerializer with many=True

我不知道如何向接受 many=True 的 ModelSerializer 添加其他字段。这是我的所有代码:

视图集:

 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 序列化程序。它还具有内部 Many=True 个字段

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', ]

现在我的 ContractGetSerializer return 是一个包含所有合同的 ReturnList。如何向该 ReturnList 添加其他字段并使其成为字典?

例如,我只需要 return 5 个近期 合同(按时间戳过滤)。 另外,我需要添加 total SIGNED contractstotal PENDING contracts,计算所有合同数据,这样我的前端就不需要这样做了。

我现在的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"
        }
      ]
    },
 
  ]
}

我想要的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"
        }
      ]
    },
 
  ]
}

有多种方法可以做到这一点,但我认为在序列化程序中这样做更好。

我会做这样的事情:

正在查看

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

在序列化程序中

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

    def get_recents_count(self, obj):
        # I don't know how is 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', ]

如果你喜欢在你的视图中也可以这样做而不是编写一个新的序列化程序 例如:

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)