如何在many=True的情况下向ModelSerializer添加其他字段,如对象计数



我不知道如何向接受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 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)

相关内容

最新更新