如何在DRF中用一个请求创建多个对象(相关的)?

2024-10-01 17:24:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个类代表一个作业,一个类代表一个标记,它描述一个作业,然后我有一个类在它们之间建立关系(连接表),所以一个作业可以用多个标记来描述:

class JobTag(models.Model):
    job = models.ForeignKey(Job, unique=False, related_name='jobtags')
    tag = models.ForeignKey(Tag, unique=False, related_name='Tag_For_Job')

    created_time = models.DateTimeField(auto_now_add = True)
    modified_time = models.DateTimeField(auto_now = True)

    class Meta:
        unique_together = ('job', 'tag',)

    def __unicode__(self):
        return 'Tag '+self.tag.name +' for job '+ self.job.name

然后我有序列化程序:

^{pr2}$

所以GET请求的http响应是:

{
        "url": "http://127.0.0.1:8000/api/jobs/2/",
        "name": "Odprac mi sneh",
        "employer": "http://127.0.0.1:8000/api/users/4/",
        "jobtags": [
            {
                "tag": {
                    "url": "http://127.0.0.1:8000/api/tags/2/",
                    "name": "Odhadzovanie snehu",
                    "badge_pic": "http://127.0.0.1:8000/media/pictures/tags/0005.jpg"
                }
            }
        ],
        "description": "blablabla"
    }

我的问题很明显,我如何创建一个作业实例,并用一个POST-http请求将它们与相关的jobtag持久化?在

我试着重复这个方法http://www.django-rest-framework.org/api-guide/serializers/#writable-nested-representations。在

class JobSerializer(serializers.HyperlinkedModelSerializer):
        jobtags=JobTagSerializer(many=True)
        class Meta:
            model = Job
            fields = ('url','name', 'employer','jobtags','description')
            read_only_fields = ('employer',)
        def create(self, validated_data):
            jobtag_data = validated_data.pop('jobtags')
            job = Job.objects.create(**validated_data)
            JobTag.objects.create(job=job, **jobtag_data)
            return job

但它返回了“create()argument after**must a mapping,not list”错误,那么应该怎么办请求数据json看起来像?在

或者这种方法不能用在我的案例中,我应该做一些完全不同的事情吗?在

我会很感激你的帮助。在

编辑

如果我试图访问列表:

def create(self, validated_data):
        jobtag_data = validated_data.pop('jobtags')
        job = Job.objects.create(**validated_data)
        JobTag.objects.create(job=job, **jobtag_data[0])
        return job

我生成另一个错误:“Cannot assign”OrderedDict():作业标签.tag标记必须是“instance” 所以我猜我发布的json格式不对?我用这种方式尝试了topost数据:

{
        "name": "Odprac mi sneh",
        "jobtags": [
            {
                "tag": {
                    "url": "http://127.0.0.1:8000/api/tags/2/"
                }
            }
        ],
        "description": "veela sneu nemam ruky makam makam makamam",           
    }

Tags: nameselfapihttpdatamodelstagcreate
2条回答

如果有其他人面临这种情况,我想出的最合适的解决方案是,在创建对象时使用jobtags的超链接序列化,并将嵌套序列化用作输出:

我为每种情况编写了序列化程序,用于序列化发送到客户机的数据:

class JobTagNestedSerializer(serializers.HyperlinkedModelSerializer):
    tag = TagSerializer()
    class Meta:
        model = JobTag
        fields = ('tag',)
        depth=1



class JobNestedSerializer(serializers.HyperlinkedModelSerializer):
    jobtags=JobTagNestedSerializer(many=True,read_only=True)
    class Meta:
        model = Job
        fields = ('url','name', 'employer','jobtags','description')
        read_only_fields = ('employer',)

对于创建新作业,对于从客户端发送到DRF的数据:

^{pr2}$

所以DRF希望客户端的POST-json看起来像:

{
        "name": "Odprac mi sneh",
        "employer": "http://127.0.0.1:8000/api/users/4/",
        "jobtags": [
            {
                "tag": "http://127.0.0.1:8000/api/tags/2/"
            },
            {
                "tag": "http://127.0.0.1:8000/api/tags/5/"
            }
        ],
        "description": "veela sneu nemam ruky makam makam makamam"
    }

我认为您应该在POST数据中提供每个标记的id,而不是{},如下所示:

{
    "name": "Odprac mi sneh",
    "tags": [
        {
            "id": 2
        },
        {
            "id": 3
        }
    ],
    "description": "veela sneu nemam ruky makam makam makamam"
}

然后,在您的create方法中,您应该能够迭代标记:

^{pr2}$

相关问题 更多 >

    热门问题