mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-08-05 04:50: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.
|
||||
|
||||
|
||||
## 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` may be used to represent the target of the relationship using a hyperlink.
|
||||
|
|
|
@ -231,6 +231,36 @@ class PrimaryKeyRelatedField(RelatedField):
|
|||
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):
|
||||
lookup_field = 'pk'
|
||||
view_name = None
|
||||
|
|
Loading…
Reference in New Issue
Block a user