4👍
Alright so I found a different approach that works.
I added an IntegerField serializer for the owner relation. I also had to set the owner relation to read_only=True.
This is the json I am sending via POST:
{
name: "Hello!"
owner_id: 1
}
This is my serializer:
class ClientfileSerializer(serializers.ModelSerializer):
owner_id = serializers.IntegerField()
owner = ContactSerializer(read_only=True)
class Meta():
model = Clientfile
fields = (
'id',
'owner_id',
'owner',
)
It seems less cool than the first way, but it does the job.
Plus I don’t want to create a new owner, but just select one that is already in the database. So maybe it’s more semantic to only have the ID and not the full set of information posted via Json.
17👍
In Django REST Framework AutoField
fields (those that are automatically generated) are defaulted to read-only. From the docs:
read_only
Set this to
True
to ensure that the field is used when
serializing a representation, but is not used when creating or
updating an instance during deserialization.Defaults to
False
You can see this by inspecting your serializer by printing the representation in your shell:
serializer = ClientfileSerializer()
print repr(serializer)
You can override this by setting read_only=False
against the id field in the extra_kwargs
:
class ContactSerializer(serializers.ModelSerializer):
class Meta:
model = Contact
fields = (
'id',
'first_name',
'last_name',
)
extra_kwargs = {'id': {'read_only': False}}
class ClientfileSerializer(serializers.ModelSerializer):
owner = ContactSerializer(read_only=False)
class Meta():
model = Clientfile
fields = (
'id',
'name',
'owner',
)
extra_kwargs = {'id': {'read_only': False}}
3👍
You can try something like this:
class YourModelSerializer(serializers.ModelSerializer):
class Meta:
model = YourModel
fields = ('id', 'field1', 'field2')
def to_internal_value(self, data):
"""
Dict of native values <- Dict of primitive datatypes.
Add instance key to values if `id` present in primitive dict
:param data:
"""
obj = super(YourModelSerializer, self).to_internal_value(data)
instance_id = data.get('id', None)
if instance_id:
obj['instance'] = YourModel.objects.get(id=instance_id)
return obj
Then in serializer validated data you should have “instance” key if request.data has “id” key.
Also You can add just “id” instead of full instance/object.
0👍
The top voted answer does solve the issue but it raises a new one as mentioned in the comments we can no longer create a new record as it will thrown ac exception saying is required. We can set id to required=False then id will be available in validated_data and it wont be required to set it manually
id = serializers.IntegerField(required=False) <- Like this
class Meta:
model = Details
fields = ('id', 'product_name', 'description', 'specification', 'make_model',
'brand', 'quantity',)
- How can I disable a model field in a django form
- Django 1.7 where to put the code to add Groups programmatically?
- Why isn't psycopg2 executing any of my SQL functions? (IndexError: tuple index out of range)
- Creating UTF-8 JsonResponse in Django