1👍
✅
With the below snippet, you can serialize the PK value into required data and while saving you can give only PK value
from django.core.exceptions import ObjectDoesNotExist, ValidationError
from django.utils.encoding import smart_text
from rest_framework import serializers
class CustomRelatedField(serializers.RelatedField):
"""
Represents a primary key relationship with {'pk':1,'name': 'foo'}
"""
read_only = False
default_error_messages = {
'does_not_exist': ("Invalid pk '%s' - object does not exist."),
'incorrect_type': ('Incorrect type. Expected {"id": 1} format , received %s.'),
}
def __init__(self, *args, **kwargs):
self.fields = kwargs.pop('fields', ('id',))
return super(CustomRelatedField, self).__init__(*args, **kwargs)
def to_native(self, obj):
data = {'id':obj.pk}
for field in self.fields:
value = getattr(obj, field)
data[field] = value
return data
def from_native(self, data):
if isinstance(data, int):
data = {'id':data}
if not isinstance(data, dict):
received = type(data).__name__
msg = self.error_messages['incorrect_type'] % received
raise ValidationError(msg)
if self.queryset is None:
raise Exception('Writable related fields must include a `queryset` argument')
try:
return self.queryset.get(pk=data.get('id'))
except ObjectDoesNotExist:
msg = self.error_messages['does_not_exist'] % smart_text(data)
raise ValidationError(msg)
except (TypeError, ValueError):
received = type(data).__name__
msg = self.error_messages['incorrect_type'] % received
raise ValidationError(msg)
and
class FooSerializer(serializers.ModelSerializer):
bar = CustomRelatedField(fields=('id','name', 'number'))
class Meta:
model = Foo
fields = ("name", "bar")
Source:stackexchange.com