Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python django REST中有多个可读取嵌套序列化程序_Python_Django_Django Rest Framework_Django Serializer - Fatal编程技术网

Python django REST中有多个可读取嵌套序列化程序

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"

我正在运行一个django应用程序,使用REST将数据发送到我的API

我有一个包含许多项目的网络,一个项目可以属于许多网络

我想通过以下请求发送此数据集:

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'