Python django REST中有多个可读取嵌套序列化程序
我正在运行一个django应用程序,使用REST将数据发送到我的API 我有一个包含许多项目的网络,一个项目可以属于许多网络 我想通过以下请求发送此数据集:Python django REST中有多个可读取嵌套序列化程序,python,django,django-rest-framework,django-serializer,Python,Django,Django Rest Framework,Django Serializer,我正在运行一个django应用程序,使用REST将数据发送到我的API 我有一个包含许多项目的网络,一个项目可以属于许多网络 我想通过以下请求发送此数据集: payload = { "name": "my great testnetwork", "type_network": "xyz", "projects" : [ { "project_name"
payload = {
"name": "my great testnetwork",
"type_network": "xyz",
"projects" : [
{
"project_name": "Brasil",
},
{
"project_name": "Sweden",
},
],
"creation_date": "2020-05-15T15:57:27.399455Z"
}
我不想创建项目名称,它们已经在数据库中。我只想让它像普通的FK一样工作,在这里我指定了项目名称,它显示在我的API中。它应该只涉及它们
现在的情况是,当我这样发送项目列表时,它仍然是空的
这就是我得到的:
{
"id": 6,
"name": "my great test",
"type_network": "xyz",
"projects": [],
"creation_date": "2020-05-15T19:00:05.947542Z"
}
但我需要清单上的项目
我的序列化程序如下所示:
class NetworkSerializer(serializers.ModelSerializer):
"""Serializer for Network.
Add extra field buildings from NestedProjectSerializer.
"""
projects = NestedProjectSerializer(
many=True,
read_only=True,
help_text="Many to many relation. Project instances expected."
)
class Meta:
model = Network
fields = (
'id',
'name',
'projects',
'creation_date',
)
好的,所以我尝试覆盖可写嵌套序列化程序的create方法,但我想我不需要这个,对吗?因为我不想创建新对象。然后我还尝试使用PrimaryKeyRelatedField
,但我得到的错误是pk无效(当传递查询集时),或者它不显示项目(当使用只读=True时)
我有点困在这里了。有人能帮我一下吗?非常感谢你的时间和帮助。非常感谢
我很乐意提供更多的代码或澄清,如果需要的话
我的模型:
class Project(models.Model):
project_name = models.CharField(max_length=120, primary_key=True, unique=True)
location = models.CharField(max_length=120, null=True, blank=True)
class Network(models.Model):
name = models.CharField(
max_length=120,
null=True,
blank=True,
help_text="Name of network. String expected."
)
projects = models.ManyToManyField(
Project,
default=None,
blank=True,
help_text="Many to many relation. Project instances expected."
)
creation_date = models.DateTimeField(
auto_now=True
)
我觉得我必须重写create方法。。。项目名称为pk btw
编辑:发送如下数据:
payload = {
"name": "my great testnetwork",
# "projects" : [
# {
# "project_name": "frankfurt",
# }
# ],
"projects_data" : [
{
"project_name": "Brasil",
}
],
"creation_date": "2020-05-15T15:57:27.399455Z"
}
r = requests.request('post', 'http://localhost:8000/myendpoint', json=payload, headers=headers)
print(r.text)
print(r.status_code)
您需要将代码更新为如下所示:
from rest_framework import serializers
class NetworkSerializer(serializers.ModelSerializer):
"""Serializer for Network.
Add extra field buildings from NestedProjectSerializer.
"""
projects_data = serializers.SerializerMethodField()
class Meta:
model = Network
fields = (
'id',
'name',
'projects',
'projects_data',
'creation_date',
)
def get_projects_data(self, obj):
projects = obj.projects.all()
return NestedProjectSerializer(projects, many=True).data
我希望这有帮助
如果定义嵌套序列化程序,则在创建记录时将始终卡住。因为create方法需要来自项目序列化程序的序列化数据
参考:
编辑:
新序列化程序
from rest_framework import serializers
class NetworkSerializer(serializers.ModelSerializer):
"""Serializer for Network.
Add extra field buildings from NestedProjectSerializer.
"""
projects = NestedProjectSerializer(many=True, required=False)
class Meta:
model = Network
fields = (
'id',
'name',
'projects',
'projects_data',
'creation_date',
)
def create(self, validated_data):
projects = validated_data.pop("projects")
network_obj = Network.objects.create(**validated_data)
for project in projects:
network_obj.projects.add(Project.objects.create(**project))
network_obj.save()
return network_obj
我已根据您的要求重写了创建方法您需要将代码更新为以下内容:
from rest_framework import serializers
class NetworkSerializer(serializers.ModelSerializer):
"""Serializer for Network.
Add extra field buildings from NestedProjectSerializer.
"""
projects_data = serializers.SerializerMethodField()
class Meta:
model = Network
fields = (
'id',
'name',
'projects',
'projects_data',
'creation_date',
)
def get_projects_data(self, obj):
projects = obj.projects.all()
return NestedProjectSerializer(projects, many=True).data
我希望这有帮助
如果定义嵌套序列化程序,则在创建记录时将始终卡住。因为create方法需要来自项目序列化程序的序列化数据
参考:
编辑:
新序列化程序
from rest_framework import serializers
class NetworkSerializer(serializers.ModelSerializer):
"""Serializer for Network.
Add extra field buildings from NestedProjectSerializer.
"""
projects = NestedProjectSerializer(many=True, required=False)
class Meta:
model = Network
fields = (
'id',
'name',
'projects',
'projects_data',
'creation_date',
)
def create(self, validated_data):
projects = validated_data.pop("projects")
network_obj = Network.objects.create(**validated_data)
for project in projects:
network_obj.projects.add(Project.objects.create(**project))
network_obj.save()
return network_obj
我已根据您的要求添加了create方法。非常感谢。我已经更新了我的评论。请尝试让我知道这个问题是否仍然存在。非常感谢希瓦姆!当我按照您所说的方式更新代码并发送数据时,我得到了错误:{'projects':['Invalid pk'{'project\u name\':\'Brasil\'}”-对象不存在。]}
但我已经验证了它确实存在。可能这与作为主键的project_name有关?您只需要发送项目的主键,即project_id,而不是发送整个项目的数据。如果我在这里速度慢,那么如何发送“仅发送主键”?我想这就是我正在做的(我用我用来发送数据的代码更新了我的问题)。但是,如果我省略projects字段并在projects\u data中发送数据,我仍然会得到一个空的projects\u数据字段,如下所示:{'id','name':'my great testnetwork','projects':[],'projects\u data':[],'creation\u date':'2020-05-18T12:48:57.241167Z'
添加。非常感谢。我已经更新了我的评论。请尝试让我知道这个问题是否仍然存在。非常感谢希瓦姆!当我按照您所说的方式更新代码并发送数据时,我得到了错误:{'projects':['Invalid pk'{'project\u name\':\'Brasil\'}”-对象不存在。]}
但我已经验证了它确实存在。可能这与作为主键的project_name有关?您只需要发送项目的主键,即project_id,而不是发送整个项目的数据。如果我在这里速度慢,那么如何发送“仅发送主键”?我想这就是我正在做的(我用我用来发送数据的代码更新了我的问题)。但是如果我省略projects字段并在projects\u data中发送我的数据,我仍然会得到一个空的projects\u数据字段,如下所示:{'id':17,'name':'my great testnetwork','projects':[],'projects\u data':[],'creation\u date':'2020-05-18T12:48:57.241167Z'