django - 在序列化程序中更改创建时的返回类型
问题描述
我有以下两个序列化程序:
class ProgramSerializer(serializers.ModelSerializer):
class Meta:
from radio.models import Program
model = Program
fields = ('id', 'title')
class UserRecentlyPlayedSerializer(serializers.ModelSerializer):
program_data = ProgramSerializer(read_only=True)
class Meta:
model = UserRecentlyPlayed
fields = ('id', 'user', 'program', 'program_data',)
它们基于以下模型:
class Program(models.Model):
title = models.CharField(max_length=64)
class UserRecentlyPlayed(models.Model):
user = models.ForeignKey(User)
program = models.ForeignKey(Program)
我要做的是:在创建时,我希望能够以以下方式创建 UserRecentlyPlayed 的新实例:
{
"user": "...user id ....",
"program": "....program id...."
}
但是,当我返回一个列表时,我想返回以下内容:
[{
"id": "... id .... ",
"user": ".... user id .....",
"program": {"id": "...program id...", "title": "...title..." }
}]
这些在以下视图中被调用:
class RecentlyPlayed(generics.ListCreateAPIView):
serializer_class = UserRecentlyPlayedSerializer
不幸的是,这不起作用。什么是正确的魔法?
解决方案
您可以将您program_data
的序列化程序重命名为program
,也可以为嵌套序列化程序指定源。
那应该根据您的需要返回 list 的输出。
class UserRecentlyPlayedSerializer(serializers.ModelSerializer):
program = ProgramSerializer(read_only=True)
class Meta:
model = UserRecentlyPlayed
fields = ('id', 'user', 'program',)
或者
class UserRecentlyPlayedSerializer(serializers.ModelSerializer):
program_data = ProgramSerializer(read_only=True, source='program')
class Meta:
model = UserRecentlyPlayed
fields = ('id', 'user', 'program_data',)
为了支持创建相同的 json 输入,最简单的方法是为输入创建另一个序列化程序:
class UserRecentlyPlayedSerializerInput(serializers.ModelSerializer):
program = serializers.PrimaryKeyRelatedField(queryset=Program.objects.all())
class Meta:
model = UserRecentlyPlayed
fields = ('id', 'user', 'program',)
当请求为 POST/PUT/PATCH 时,在您的视图中使用它:
class RecentlyPlayed(generics.ListCreateAPIView):
serializer_class = UserRecentlyPlayedSerializer
def get_serializer_class(self):
if self.request.method.lower() == 'get':
return self.serializer_class
return UserRecentlyPlayedSerializerInput
虽然这对于“获取”很有用,但我希望在创建后看到相同的结果。我仍然看到 {"program": "...id...."
为此,您必须在视图中稍微更改 create 方法的实现
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
instance = serializer.save()
headers = self.get_success_headers(serializer.data)
oser = UserRecentlyPlayedSerializer(instance)
return Response(oser.data, status=status.HTTP_201_CREATED,
headers=headers)
推荐阅读
- python - 在 macOS 问题上安装 py3exiv2
- service-worker - 带有 Service Worker 的 CSP
- c# - C# 将文本文件中的 REG_MULTI_SZ 值转换为字符串
- javascript - 如何将动态创建的文本框值从 javascript 传递到 mvc 控制器
- c# - 用c#在2个sql server数据库之间进行数据翻译#
- machine-learning - 稀疏张量没有步幅
- xml - 明智地保存和读取更改的配置(存储在 XML 文件中)
- python - GitHub 上 Jupyter 笔记本中的目录
- node.js - 尝试重构 Express 路线
- android - 如何使用最新的 R8 Shrinker 版本