django rest框架:来自数据don';更新模型ID

django rest框架:来自数据don';更新模型ID,django,django-rest-framework,Django,Django Rest Framework,我有一个简单的序列化程序,如下所示: class CategoryCreationSerializer(serializers.ModelSerializer): class Meta: model = Category Category有一个id字段(Django主键),我不明白序列化程序为什么不更新它 场景:我有一篇带有给定类别的博客文章。我正在用一个不同的类别(已经在数据库中创建)更新BlogPost。因此,POST请求将包含所有BlogPost信息以及更新id

我有一个简单的序列化程序,如下所示:

class CategoryCreationSerializer(serializers.ModelSerializer):

    class Meta:
        model = Category
Category有一个id字段(Django主键),我不明白序列化程序为什么不更新它

场景:我有一篇带有给定类别的博客文章。我正在用一个不同的类别(已经在数据库中创建)更新BlogPost。因此,POST请求将包含所有BlogPost信息以及更新id的新类别JSON对象:

{
    "id": 1,
    "title": "My first blog post",
    "category": {
        "id": 3,
        "name": "Techology"
    }
}
问题是当我这样做的时候:

category_data = data.get('category')
    if category_data is not None:
        category_serializer = CategoryCreationSerializer(data=category_data)
        if category_serializer.is_valid():
            blog_post.category = category_serializer.object
内部类别标题将更新,但id字段将为无。 你能解释一下为什么吗


干杯,Emanuele。

默认情况下,Django REST框架自动生成的
id
字段。因此,
id
将始终为none,如果尚未附加类别,它将尝试创建一个新的
类别

您可以通过将自己的
id
字段添加到非只读的序列化程序来覆盖此字段

class CategoryCreationSerializer(serializers.ModelSerializer):
    id = serializers.IntegerField()

    class Meta:
        model = Category

默认情况下,Django REST框架自动生成的
id
字段。因此,
id
将始终为none,如果尚未附加类别,它将尝试创建一个新的
类别

您可以通过将自己的
id
字段添加到非只读的序列化程序来覆盖此字段

class CategoryCreationSerializer(serializers.ModelSerializer):
    id = serializers.IntegerField()

    class Meta:
        model = Category

这是来自on django rest framework git存储库的官方答案:

简短的回答是,默认情况下,ModelSerializer将生成 id的只读字段。(在常规视图中,您将看到 id由视图代码根据URL中的id显式设置) 您需要在序列化程序上显式声明id字段,以便 你可以让它读写

因此,我设法解决了我的问题,使序列化程序与我问题中的一样(没有
id=serializers.IntegerField()


这是来自on django rest framework git存储库的官方答案:

简短的回答是,默认情况下,ModelSerializer将生成 id的只读字段。(在常规视图中,您将看到 id由视图代码根据URL中的id显式设置) 您需要在序列化程序上显式声明id字段,以便 你可以让它读写

因此,我设法解决了我的问题,使序列化程序与我问题中的一样(没有
id=serializers.IntegerField()


这是一种“特殊情况”,其中类别将为无或现有类别。类似于blog_post的所有者。现在,当我尝试执行blog_post.is_valid()时,它将失败,并出现以下错误:“具有此ID的类别已存在。”@StErMi在初始化序列化程序时,尝试将原始的
blog_post.Category
作为
实例传递。这将使DRF进入更新模式,而不是创建模式,这似乎是您正在寻找的。我正在尝试这样做,但它似乎不起作用,或者至少在原始blog_post.category为None(空)时不起作用。明天当我有更多的时间测试时,我会更新更多的信息。谢谢。这里我得到了
IntegrityError:UNIQUE constraint failed
这是一个“特殊情况”,其中类别将为无或现有类别。类似于blog_post的所有者。现在,当我尝试执行blog_post.is_valid()时,它将失败,并出现以下错误:“具有此ID的类别已存在。”@StErMi在初始化序列化程序时,尝试将原始的
blog_post.Category
作为
实例传递。这将使DRF进入更新模式,而不是创建模式,这似乎是您正在寻找的。我正在尝试这样做,但它似乎不起作用,或者至少在原始blog_post.category为None(空)时不起作用。明天当我有更多的时间测试时,我会更新更多的信息。谢谢。我得到了
IntegrityError:唯一约束失败