Add SerializableRelatedField to fields, add description to docs.

This commit is contained in:
b.khasanov 2016-05-22 17:10:56 +03:00
parent 5cf7d4a90d
commit ee4c4680f3
2 changed files with 74 additions and 0 deletions

View File

@ -119,6 +119,50 @@ By default this field is read-write, although you can change this behavior using
* `pk_field` - Set to a field to control serialization/deserialization of the primary key's value. For example, `pk_field=UUIDField(format='hex')` would serialize a UUID primary key into its compact hex representation. * `pk_field` - Set to a field to control serialization/deserialization of the primary key's value. For example, `pk_field=UUIDField(format='hex')` would serialize a UUID primary key into its compact hex representation.
## SerializableRelatedField
`SerializableRelatedField` may be used to represent the target of the relationship using serializer passed as argument.
For example, if we pass `TrackSerializer` the following serializer:
class AlbumSerializer(serializers.ModelSerializer):
tracks = serializers.SerializableRelatedField(many=True, read_only=True)
class Meta:
model = Album
fields = ('album_name', 'artist', 'tracks')
Would serialize to a representation like this:
{
'album_name': 'The Roots',
'artist': 'Undun',
'tracks': [
{
'order': 1,
'title': 'Public Service Announcement',
'duration': 245,
},
{
'order': 2,
'title': 'What More Can I Say',
'duration': 264,
},
...
]
}
By default this field take queryset from passed `serializer`.
**Arguments**:
* `queryset` - The queryset used for model instance lookups when validating the field input. Relationships must either set a queryset explicitly, or set `read_only=True`.
* `many` - If applied to a to-many relationship, you should set this argument to `True`.
* `allow_null` - If set to `True`, the field will accept values of `None` or the empty string for nullable relationships. Defaults to `False`.
* `serializer` - Required field, serializer to represent the target of the relationship
* `serializer_params` - Parameters, passed to serializer
## HyperlinkedRelatedField ## HyperlinkedRelatedField
`HyperlinkedRelatedField` may be used to represent the target of the relationship using a hyperlink. `HyperlinkedRelatedField` may be used to represent the target of the relationship using a hyperlink.

View File

@ -231,6 +231,36 @@ class PrimaryKeyRelatedField(RelatedField):
return value.pk return value.pk
class SerializableRelatedField(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, **kwargs):
self.serializer = kwargs.pop('serializer', None)
assert self.serializer is not None, (
'SerializableRelatedField field must provide a `serializer` argument'
)
self.serializer_params = kwargs.pop('serializer_params', dict())
if 'queryset' not in kwargs:
kwargs['queryset'] = self.serializer.Meta.model.objects.all()
kwargs['style'] = {'base_template': 'input.html', 'input_type': 'numeric'}
super(SerializableRelatedField, self).__init__(**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__)
def to_representation(self, value):
return self.serializer(instance=value, context=self.context, **self.serializer_params).data
class HyperlinkedRelatedField(RelatedField): class HyperlinkedRelatedField(RelatedField):
lookup_field = 'pk' lookup_field = 'pk'
view_name = None view_name = None