在 Django 中向序列化响应添加附加数据
Posted
技术标签:
【中文标题】在 Django 中向序列化响应添加附加数据【英文标题】:Adding Additional Data to a Serialize Response in Django 【发布时间】:2021-09-17 13:28:18 【问题描述】:更新
我把我的简化问题变成了一个真实的例子。
我使用 ModelSerialzer 创建了来自模型的数据的工作发布响应,我从视图类中的发布方法调用它。我想在响应中添加其他数据。这是我的 CBV 中的相关代码:
def post(self, request, format=None):
user_profile = UserProfiles.objects.get(user=request.user.id)
service_id = user_profile.service_id
rec_filter = Recommendations.objects.values_list('resource')
if service_id > 0:
service_name = Services.objects.get(pk=service_id)
programs = Programs.objects.filter(services=service_id)
resources_filtered = Resources.objects.filter(program__in=programs).exclude(id__in=rec_filter)
else:
service_name = 'All Services'
resources_filtered = Resources.objects.exclude(id__in=rec_filter)
serializer = ResourceSerializer(resources_filtered, many=True)
#serializer.data["service"] = service_name
return Response(serializer.data)
注释掉的行是我在此处的类似帖子上添加数据库的尝试。我在 API 调用中收到 500 响应。正确的方法是什么?如果有必要,响应数据是 JSON。
这是模型序列化器:
class ResourceSerializer(serializers.ModelSerializer):
organization = OrganizationSerializer(read_only=True)
program = ProgramSerializer(read_only=True)
class Meta:
model = Resources
fields = [
'organization',
'program',
'link',
'contact',
'general_contact',
'eligibility',
'service_detail'
]
答案测试
以下是基于答案的更新代码,其中包含修复和错误的更正:
class ResourceSerializer(serializers.ModelSerializer):
organization = OrganizationSerializer(read_only=True)
program = ProgramSerializer(read_only=True)
service = serializers.SerializerMethodField()
def get_service(self, obj):
return "All Services"
class Meta:
model = Resources
fields = [
'organization',
'program',
'link',
'contact',
'general_contact',
'eligibility',
'service_detail',
'service'
]
这种方法的问题是“所有服务”的值在序列化的每一行中都会重复。它只需要一次。我还想尽量减少传输的数据。
【问题讨论】:
您可以在ResourceSerializer
中执行此操作。这不是一种选择吗?
请查看“What to do when someone answers” - Don't be a chameleon, don't be a vandal。正如帖子所建议的那样,不要随意更改您的问题,从而使现有答案无效!
另见“Follow on” question vs edit to original - when to use which?,它解释了你应该做什么。
@bdbd recousererializer 序列化单个表及其链接表。为了 KISS 的利益,我不想添加与其目的完全无关的代码。
【参考方案1】:
您可以在序列化程序本身中执行此操作。定义所需的新字段并将其添加到字段中。从资源模型中标记序列化程序中的所有字段。
class ResourceSerializer(serializers.ModelSerializer):
service = serializers.SerializerMethodField()
def get_service(self):
return "All Services"
class Meta :
model = Resources
fields = ('service') #Mark all the fields required here from resource model
【讨论】:
您的答案看起来可行。我的问题比原来的问题更复杂。我已对其进行了更新,以准确显示我需要的内容。 我尝试了答案,但它失败了,如问题中所述。我是不是搞砸了?此外,相同的数据(“所有服务”)将出现在它序列化的每一行中。我只需要一次。 已修复。您需要在 get_service 参数中添加“, obj”。【参考方案2】:最初尝试的问题是 serializer.data 是不可变的。有必要制作一个副本并添加到它。
serializer = ResourceSerializer(resources_filtered, many=True)
augmented_serializer_data = list(serializer.data)
augmented_serializer_data.append('service': 'All Services')
return Response(augmented_serializer_data)
此答案基于@andre-machado 在this question 中给出的答案。
这里的代码是与给出的其他答案一致的示例。
【讨论】:
以上是关于在 Django 中向序列化响应添加附加数据的主要内容,如果未能解决你的问题,请参考以下文章
Django:向 UserCreationForm 添加附加字段
在 Django Rest Framework 中缓存序列化程序响应