mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-08-05 13:00:12 +03:00
Add SerializableRelatedField to fields, add description to docs.
This commit is contained in:
parent
5cf7d4a90d
commit
ee4c4680f3
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user