I've a simple serializer like this:
class CategoryCreationSerializer(serializers.ModelSerializer):
class Meta:
model = Category
Category has an id field (Django primary key) and I don't get why the Serializer is not updating it.
Scenario: I've a BlogPost with a given category. I'm updating the BlogPost with a different Category (already created on the database). So the POST request will have all the BlogPost information with the new Category JSON object with the updated id:
{
"id": 1,
"title": "My first blog post",
"category": {
"id": 3,
"name": "Techology"
}
}
The problem is that when I'm doing this:
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
inside category title will be updated but the id field will be NONE.
Can you explain me why?
Cheers, Emanuele.
By default, the id
field that is automatically generated by Django REST Framework is read-only. Because of this, the id
will always be none and it will try to create a new Category
if there isn't already one attached.
You can override this by adding you own id
field to the serializer that is not read-only.
class CategoryCreationSerializer(serializers.ModelSerializer):
id = serializers.IntegerField()
class Meta:
model = Category
This is the official answer from the issue I created on django rest-framework git repository: https://github.com/tomchristie/django-rest-framework/issues/2114
Short answer though is that by default ModelSerializer will generate a
read-only field for the id. (In the generic views you'll see that the
id is set explicitly by the view code, based on the id in the URL)
You'll want to explicitly declare the id field on the serializer so
that you can make it read-write.
So I managed to solve my problem leaving the Serializer like the one in my question ( without id = serializers.IntegerField()
)
category_data = data.get('category', None)
if category_data is not None:
category_serializer = CategoryCreationSerializer(blog_post.category, data=category_data)
if category_serializer.is_valid():
category_serializer.object.id = category_data.get("id", None)
blog_post.category = category_serializer.object