【问题标题】:How to add additional fields, like count of objects to ModelSerializer with many=True如何使用 many=True 向 ModelSerializer 添加其他字段,例如对象计数
【发布时间】:2021-03-20 10:19:28
【问题描述】:

我不知道如何向接受 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 返回一个包含所有合同的 ReturnList。如何向该 ReturnList 添加其他字段并使其成为字典?

例如,我只需要返回 5 个最近 合同(按时间戳过滤)。 另外,我需要添加total SIGNED contracts 和total 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"
        }
      ]
    },
 
  ]
}

【问题讨论】:

  • 您能否在问题中添加您想要的 JSON 响应示例,以便每个人都可以给您一个好的答案
  • 已添加。你可以检查一下

标签: django django-rest-framework django-serializer


【解决方案1】:

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

我会这样做:

在视图中

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)

【讨论】:

  • 谢谢!很好的解释。不知何故,我只得到了一个合同,而不是我的 ContractResultSerializer 中的合同列表,但我想从现在开始我会自己解决它!另外,顺便问一下,你能看看我的另一个问题吗? stackoverflow.com/questions/66726368/…
  • 很高兴听到这个消息。抱歉回复晚了,我现在会检查其他问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-20
  • 2022-01-11
  • 2019-11-25
  • 1970-01-01
  • 1970-01-01
  • 2013-08-26
相关资源
最近更新 更多