Skip to content

Instantly share code, notes, and snippets.

@g-cassie
Last active August 29, 2015 14:24
Show Gist options
  • Save g-cassie/8b4c62bf2da7d791bc36 to your computer and use it in GitHub Desktop.
Save g-cassie/8b4c62bf2da7d791bc36 to your computer and use it in GitHub Desktop.
Django Rest Framework Custom Field - Embedded on read / Primary Key on write
from __future__ import unicode_literals
from django.core.exceptions import ObjectDoesNotExist
from rest_framework.relations import RelatedField
class EmbeddedPrimaryKeyRelatedField(RelatedField):
default_error_messages = {
'required': 'This field is required.',
'does_not_exist': "Invalid pk '{pk_value}' - object does not exist.",
'incorrect_type': 'Incorrect type. Expected pk value, received '
'{data_type}.',
}
def __init__(self, *args, **kwargs):
self._serializer = kwargs.pop('serializer', None)()
assert self._serializer is not None, \
'`serializer` is a required argument.'
super(EmbeddedPrimaryKeyRelatedField, self).__init__(*args, **kwargs)
def to_internal_value(self, data):
try:
return self.get_queryset().get(pk=data)
except ObjectDoesNotExist:
self.fail('does_not_exist', pk_value=data)
except (TypeError, ValueError):
self.fail('incorrect_type', data_type=type(data).__name__)
@property
def fields(self):
return self._serializer.fields
def __iter__(self):
for field in self._serializer:
yield field
def __getitem__(self, attr_name):
return self._serializer[attr_name]
def to_representation(self, data):
return self._serializer.to_representation(data)
class PersonSerializer(serializers.ModelSerializer):
company = EmbeddedPrimaryKeyRelatedField(many=True, queryset=Company.objects.all(),
serializer=CompanySerializer)
class Meta:
model = Person
fields = ('name', 'company')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment