Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.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 RESTful API中序列化多个关系中的数据列表并正确创建嵌套对象?_Python_Django_Rest_Serialization_Many To Many - Fatal编程技术网

Python 如何在Django RESTful API中序列化多个关系中的数据列表并正确创建嵌套对象?

Python 如何在Django RESTful API中序列化多个关系中的数据列表并正确创建嵌套对象?,python,django,rest,serialization,many-to-many,Python,Django,Rest,Serialization,Many To Many,我认为这是一个愚蠢的问题,但有几天我无法处理它。。。我有两个模型:书和作者。书可以有很多作者,作者也可以有很多书。我正在发布一本新书,我正在传递一个“标题”和一个作者列表(RESTfulAPI要求我传递一个字典列表,如下面的示例所示)。我想从这个列表中创建新的作者,但不覆盖旧作者,也不复制他们 models.py: class Authors(models.Model): name = models.CharField(max_length=50, blank=True) class

我认为这是一个愚蠢的问题,但有几天我无法处理它。。。我有两个模型:书和作者。书可以有很多作者,作者也可以有很多书。我正在发布一本新书,我正在传递一个“标题”和一个作者列表(RESTfulAPI要求我传递一个字典列表,如下面的示例所示)。我想从这个列表中创建新的作者,但不覆盖旧作者,也不复制他们

models.py:

class Authors(models.Model):
    name = models.CharField(max_length=50, blank=True)

class Book(models.Model):
    title = models.CharField(max_length=60, blank=False, null=False)
    authors = models.ManyToManyField(Authors)
serielizers.py:

class AuthorsSerializer(serializers.ModelSerializer):
    class Meta:
        model = Authors
        fields = '__all__'

class BookSerializer(serializers.ModelSerializer):
    authors = AuthorsSerializer(many=True)
    class Meta:
        model = Book
        fields = ['id', 'title', 'authors']
        depth = 1

    def create(self, validated_data):
        authors_data = validated_data.pop('authors')
        book = Book.objects.create(**validated_data)
        for autor in authors_data:
            Authors.objects.create(book=book, **autor)
        return book
views.py:

class BooksList(viewsets.ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
URL.py:

book_list = BooksList.as_view({
    'get': 'list',
    'post': 'create',
})

book_detail = BookDetails.as_view({
    'get': 'retrieve',
    'put': 'update',
    'patch': 'partial_update',
    'delete': 'destroy'})

authors_list = AuthorsList.as_view({
    'get': 'list',
    'post': 'create'})


urlpatterns = format_suffix_patterns([
    path('books/', book_list, name='book_list'),
    path('books/<int:pk>', book_detail, name='book_detail'),
    path('authors/', authors_list, name='authors_list'),
])
a我收到一个新书对象,数据库中有两位作者,但他们没有关联。我得到的答案是这样的:

{
    "title": "Anything",
    "authors": [{"name":"First Guy"},{"name":"Second Guy"}],
}
HTTP 201 Created
Allow: GET, POST, PUT, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 8,
    "title": "Anything",
    "authors": [],
}
   {
        "id": 8,
        "name": "First Guy"
    },
    {
        "id": 9,
        "name": "Second Guy"
    }
]
当我得到作者列表时,他们是这样的:

{
    "title": "Anything",
    "authors": [{"name":"First Guy"},{"name":"Second Guy"}],
}
HTTP 201 Created
Allow: GET, POST, PUT, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 8,
    "title": "Anything",
    "authors": [],
}
   {
        "id": 8,
        "name": "First Guy"
    },
    {
        "id": 9,
        "name": "Second Guy"
    }
]
我希望收到的视图是:

{
"title": "Anyting",
"authors": [
          "First Guy",
          "Second Guy"
        ]
}

为什么他们不相关,我在书中没有看到他们。作者?我要求的方法是错误的吗?当我通过管理面板执行此操作时,我可以将“Authors”与“Book”连接起来,它通过这种方式工作,但当然它应该通过API调用工作。我尝试了几十种配置,括号的组合,其他类型的关系,不同的参数,读了很多od文章/文档/youtube等,我无法入睡,因为这。。。因为我很笨,我还没有找到“更新方法”,所以如果有人能解释这两种方法就好了。谢谢你的建议

问题出在
BookSerializer
中的
create
方法中。创建实例时不能直接分配多对多相关对象,即
Authors.objects.create(book=book,**autor)

要将
作者
对象与
书籍
相关联,您需要像这样做:

def创建(自我验证的_数据):
authors\u data=validated\u data.pop(‘authors’)
book=book.objects.create(**已验证的_数据)
对于作者中的autor\u数据:
author\u instance=Authors.objects.create(**autor)
book.authors.add(author\u实例)
#或author\u instance.book\u set.add(book)
回执

ooo谢谢-现在,作者列表与书籍相关,但当作者在数据库中时,它会复制他。我是否应该使用某种形式的“如果”语句?@noumen您必须以某种方式确定即将到来的作者,可能的解决方案是在您的请求正文中发送一个
id
,并检查DB中是否存在该作者。但是,我建议您不要创建
作者
对象,而是发送现有作者的id-s并将其设置为图书