3.0 docs and tidy-up for serializer relationships

This commit is contained in:
Tom Christie 2014-11-26 11:30:49 +00:00
parent b4550c65dd
commit 5a5a73c7fe

View File

@ -16,6 +16,20 @@ Relational fields are used to represent model relationships. They can be applie
--- ---
#### Inspecting automatically generated relationships.
When using the `ModelSerializer` class, serializer fields and relationships will be automatically generated for you. Inspecting these automatically generated fields can be a useful tool for determining how to customize the relationship style.
To do so, open the Django shell, using `python manage.py shell`, then import the serializer class, instantiate it, and print the object representation…
>>> from myapp.serializers import AccountSerializer
>>> serializer = AccountSerializer()
>>> print repr(serializer) # Or `print(repr(serializer))` in Python 3.x.
AccountSerializer():
id = IntegerField(label='ID', read_only=True)
name = CharField(allow_blank=True, max_length=100, required=False)
owner = PrimaryKeyRelatedField(queryset=User.objects.all())
# API Reference # API Reference
In order to explain the various types of relational fields, we'll use a couple of simple models for our examples. Our models will be for music albums, and the tracks listed on each album. In order to explain the various types of relational fields, we'll use a couple of simple models for our examples. Our models will be for music albums, and the tracks listed on each album.
@ -37,14 +51,14 @@ In order to explain the various types of relational fields, we'll use a couple o
def __unicode__(self): def __unicode__(self):
return '%d: %s' % (self.order, self.title) return '%d: %s' % (self.order, self.title)
## RelatedField ## StringRelatedField
`RelatedField` may be used to represent the target of the relationship using its `__unicode__` method. `StringRelatedField` may be used to represent the target of the relationship using its `__unicode__` method.
For example, the following serializer. For example, the following serializer.
class AlbumSerializer(serializers.ModelSerializer): class AlbumSerializer(serializers.ModelSerializer):
tracks = serializers.RelatedField(many=True) tracks = serializers.StringRelatedField(many=True)
class Meta: class Meta:
model = Album model = Album
@ -99,9 +113,9 @@ By default this field is read-write, although you can change this behavior using
**Arguments**: **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`. * `many` - If applied to a to-many relationship, you should set this argument to `True`.
* `required` - If set to `False`, the field will accept values of `None` or the empty-string for nullable relationships. * `allow_null` - If set to `True`, the field will accept values of `None` or the empty string for nullable relationships. Defaults to `False`.
* `queryset` - By default `ModelSerializer` classes will use the default queryset for the relationship. `Serializer` classes must either set a queryset explicitly, or set `read_only=True`.
## HyperlinkedRelatedField ## HyperlinkedRelatedField
@ -110,8 +124,11 @@ By default this field is read-write, although you can change this behavior using
For example, the following serializer: For example, the following serializer:
class AlbumSerializer(serializers.ModelSerializer): class AlbumSerializer(serializers.ModelSerializer):
tracks = serializers.HyperlinkedRelatedField(many=True, read_only=True, tracks = serializers.HyperlinkedRelatedField(
view_name='track-detail') many=True,
read_only=True,
view_name='track-detail'
)
class Meta: class Meta:
model = Album model = Album
@ -134,11 +151,12 @@ By default this field is read-write, although you can change this behavior using
**Arguments**: **Arguments**:
* `view_name` - The view name that should be used as the target of the relationship. If you're using [the standard router classes][routers] this wil be a string with the format `<modelname>-detail`. **required**. * `view_name` - The view name that should be used as the target of the relationship. If you're using [the standard router classes][routers] this will be a string with the format `<modelname>-detail`. **required**.
* `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`. * `many` - If applied to a to-many relationship, you should set this argument to `True`.
* `required` - If set to `False`, the field will accept values of `None` or the empty-string for nullable relationships. * `allow_null` - If set to `True`, the field will accept values of `None` or the empty string for nullable relationships. Defaults to `False`.
* `queryset` - By default `ModelSerializer` classes will use the default queryset for the relationship. `Serializer` classes must either set a queryset explicitly, or set `read_only=True`.
* `lookup_field` - The field on the target that should be used for the lookup. Should correspond to a URL keyword argument on the referenced view. Default is `'pk'`. * `lookup_field` - The field on the target that should be used for the lookup. Should correspond to a URL keyword argument on the referenced view. Default is `'pk'`.
* `lookup_url_kwarg` - The name of the keyword argument defined in the URL conf that corresponds to the lookup field. Defaults to using the same value as `lookup_field`.
* `format` - If using format suffixes, hyperlinked fields will use the same format suffix for the target unless overridden by using the `format` argument. * `format` - If using format suffixes, hyperlinked fields will use the same format suffix for the target unless overridden by using the `format` argument.
## SlugRelatedField ## SlugRelatedField
@ -148,8 +166,11 @@ By default this field is read-write, although you can change this behavior using
For example, the following serializer: For example, the following serializer:
class AlbumSerializer(serializers.ModelSerializer): class AlbumSerializer(serializers.ModelSerializer):
tracks = serializers.SlugRelatedField(many=True, read_only=True, tracks = serializers.SlugRelatedField(
slug_field='title') many=True,
read_only=True,
slug_field='title'
)
class Meta: class Meta:
model = Album model = Album
@ -175,9 +196,9 @@ When using `SlugRelatedField` as a read-write field, you will normally want to e
**Arguments**: **Arguments**:
* `slug_field` - The field on the target that should be used to represent it. This should be a field that uniquely identifies any given instance. For example, `username`. **required** * `slug_field` - The field on the target that should be used to represent it. This should be a field that uniquely identifies any given instance. For example, `username`. **required**
* `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`. * `many` - If applied to a to-many relationship, you should set this argument to `True`.
* `required` - If set to `False`, the field will accept values of `None` or the empty-string for nullable relationships. * `allow_null` - If set to `True`, the field will accept values of `None` or the empty string for nullable relationships. Defaults to `False`.
* `queryset` - By default `ModelSerializer` classes will use the default queryset for the relationship. `Serializer` classes must either set a queryset explicitly, or set `read_only=True`.
## HyperlinkedIdentityField ## HyperlinkedIdentityField
@ -245,9 +266,9 @@ Would serialize to a nested representation like this:
# Custom relational fields # Custom relational fields
To implement a custom relational field, you should override `RelatedField`, and implement the `.to_native(self, value)` method. This method takes the target of the field as the `value` argument, and should return the representation that should be used to serialize the target. To implement a custom relational field, you should override `RelatedField`, and implement the `.to_representation(self, value)` method. This method takes the target of the field as the `value` argument, and should return the representation that should be used to serialize the target. The `value` argument will typically be a model instance.
If you want to implement a read-write relational field, you must also implement the `.from_native(self, data)` method, and add `read_only = False` to the class definition. If you want to implement a read-write relational field, you must also implement the `.to_internal_value(self, data)` method.
## Example ## Example
@ -256,7 +277,7 @@ For, example, we could define a relational field, to serialize a track to a cust
import time import time
class TrackListingField(serializers.RelatedField): class TrackListingField(serializers.RelatedField):
def to_native(self, value): def to_representation(self, value):
duration = time.strftime('%M:%S', time.gmtime(value.duration)) duration = time.strftime('%M:%S', time.gmtime(value.duration))
return 'Track %d: %s (%s)' % (value.order, value.name, duration) return 'Track %d: %s (%s)' % (value.order, value.name, duration)
@ -350,7 +371,7 @@ We could define a custom field that could be used to serialize tagged instances,
A custom field to use for the `tagged_object` generic relationship. A custom field to use for the `tagged_object` generic relationship.
""" """
def to_native(self, value): def to_representation(self, value):
""" """
Serialize tagged objects to a simple textual representation. Serialize tagged objects to a simple textual representation.
""" """
@ -360,9 +381,9 @@ We could define a custom field that could be used to serialize tagged instances,
return 'Note: ' + value.text return 'Note: ' + value.text
raise Exception('Unexpected type of tagged object') raise Exception('Unexpected type of tagged object')
If you need the target of the relationship to have a nested representation, you can use the required serializers inside the `.to_native()` method: If you need the target of the relationship to have a nested representation, you can use the required serializers inside the `.to_native()` method:
def to_native(self, value): def to_representation(self, value):
""" """
Serialize bookmark instances using a bookmark serializer, Serialize bookmark instances using a bookmark serializer,
and note instances using a note serializer. and note instances using a note serializer.
@ -404,7 +425,6 @@ attributes are not configured to correctly match the URL conf.
#### get_object(self, queryset, view_name, view_args, view_kwargs) #### get_object(self, queryset, view_name, view_args, view_kwargs)
This method should the object that corresponds to the matched URL conf arguments. This method should the object that corresponds to the matched URL conf arguments.
May raise an `ObjectDoesNotExist` exception. May raise an `ObjectDoesNotExist` exception.
@ -425,25 +445,6 @@ For example, if all your object URLs used both a account and a slug in the the U
--- ---
## Deprecated APIs
The following classes have been deprecated, in favor of the `many=<bool>` syntax.
They continue to function, but their usage will raise a `PendingDeprecationWarning`, which is silent by default.
* `ManyRelatedField`
* `ManyPrimaryKeyRelatedField`
* `ManyHyperlinkedRelatedField`
* `ManySlugRelatedField`
The `null=<bool>` flag has been deprecated in favor of the `required=<bool>` flag. It will continue to function, but will raise a `PendingDeprecationWarning`.
In the 2.3 release, these warnings will be escalated to a `DeprecationWarning`, which is loud by default.
In the 2.4 release, these parts of the API will be removed entirely.
For more details see the [2.2 release announcement][2.2-announcement].
---
# Third Party Packages # Third Party Packages
The following third party packages are also available. The following third party packages are also available.