From ed93e13a1c6f792e14176bdaa5e96d0fa2c63a2f Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Mon, 1 Dec 2014 12:20:07 +0000 Subject: Update documentation --- api-guide/relations/index.html | 110 +++++++++++++++++++++++++---------------- 1 file changed, 67 insertions(+), 43 deletions(-) (limited to 'api-guide/relations') diff --git a/api-guide/relations/index.html b/api-guide/relations/index.html index 3f3a2460..0fe39d35 100644 --- a/api-guide/relations/index.html +++ b/api-guide/relations/index.html @@ -62,7 +62,7 @@
Note: This is the documentation for the version 3.0 of REST framework. Documentation for version 2.4 is also available.
+Bad programmers worry about the code. Good programmers worry about data structures and their relationships.
@@ -462,6 +477,17 @@ Good programmers worry about data structures and their relationships.
Note: The relational fields are declared in
relations.py, but by convention you should import them from theserializersmodule, usingfrom rest_framework import serializersand refer to fields asserializers.<FieldName>.
+Inspecting automatically generated relationships.
+When using the
+ModelSerializerclass, 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
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.
-class Album(models.Model): @@ -481,11 +507,11 @@ class Track(models.Model): def __unicode__(self): return '%d: %s' % (self.order, self.title)RelatedField
-+
RelatedFieldmay be used to represent the target of the relationship using its__unicode__method.StringRelatedField
+
StringRelatedFieldmay be used to represent the target of the relationship using its__unicode__method.For example, the following serializer.
class AlbumSerializer(serializers.ModelSerializer): - tracks = serializers.RelatedField(many=True) + tracks = serializers.StringRelatedField(many=True) class Meta: model = Album @@ -533,16 +559,19 @@ class Track(models.Model):By default this field is read-write, although you can change this behavior using the
read_onlyflag.Arguments:
+
queryset- The queryset used for model instance lookups when validating the field input. Relationships must either set a queryset explicitly, or setread_only=True.- -
many- If applied to a to-many relationship, you should set this argument toTrue.- -
required- If set toFalse, the field will accept values ofNoneor the empty-string for nullable relationships.- +
queryset- By defaultModelSerializerclasses will use the default queryset for the relationship.Serializerclasses must either set a queryset explicitly, or setread_only=True.allow_null- If set toTrue, the field will accept values ofNoneor the empty string for nullable relationships. Defaults toFalse.HyperlinkedRelatedField
HyperlinkedRelatedFieldmay be used to represent the target of the relationship using a hyperlink.For example, the following serializer:
class AlbumSerializer(serializers.ModelSerializer): - tracks = serializers.HyperlinkedRelatedField(many=True, read_only=True, - view_name='track-detail') + tracks = serializers.HyperlinkedRelatedField( + many=True, + read_only=True, + view_name='track-detail' + ) class Meta: model = Album @@ -563,19 +592,23 @@ class Track(models.Model):By default this field is read-write, although you can change this behavior using the
read_onlyflag.Arguments:
-
- +
view_name- The view name that should be used as the target of the relationship. If you're using the standard router classes 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 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 setread_only=True.- -
many- If applied to a to-many relationship, you should set this argument toTrue.- -
required- If set toFalse, the field will accept values ofNoneor the empty-string for nullable relationships.- +
queryset- By defaultModelSerializerclasses will use the default queryset for the relationship.Serializerclasses must either set a queryset explicitly, or setread_only=True.allow_null- If set toTrue, the field will accept values ofNoneor the empty string for nullable relationships. Defaults toFalse.- +
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 aslookup_field.format- If using format suffixes, hyperlinked fields will use the same format suffix for the target unless overridden by using theformatargument.SlugRelatedField
SlugRelatedFieldmay be used to represent the target of the relationship using a field on the target.For example, the following serializer:
class AlbumSerializer(serializers.ModelSerializer): - tracks = serializers.SlugRelatedField(many=True, read_only=True, - slug_field='title') + tracks = serializers.SlugRelatedField( + many=True, + read_only=True, + slug_field='title' + ) class Meta: model = Album @@ -598,9 +631,9 @@ class Track(models.Model):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. requiredqueryset- The queryset used for model instance lookups when validating the field input. Relationships must either set a queryset explicitly, or setread_only=True.- -
many- If applied to a to-many relationship, you should set this argument toTrue.- -
required- If set toFalse, the field will accept values ofNoneor the empty-string for nullable relationships.- +
queryset- By defaultModelSerializerclasses will use the default queryset for the relationship.Serializerclasses must either set a queryset explicitly, or setread_only=True.allow_null- If set toTrue, the field will accept values ofNoneor the empty string for nullable relationships. Defaults toFalse.HyperlinkedIdentityField
This field can be applied as an identity relationship, such as the
@@ -637,7 +670,7 @@ class Track(models.Model): fields = ('order', 'title') class AlbumSerializer(serializers.ModelSerializer): - tracks = TrackSerializer(many=True) + tracks = TrackSerializer(many=True, read_only=True) class Meta: model = Album @@ -656,14 +689,14 @@ class AlbumSerializer(serializers.ModelSerializer): }'url'field on a HyperlinkedModelSerializer. It can also be used for an attribute on the object. For example, the following serializer: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 thevalueargument, and should return the representation that should be used to serialize the target.If you want to implement a read-write relational field, you must also implement the
+.from_native(self, data)method, and addread_only = Falseto the class definition.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 thevalueargument, and should return the representation that should be used to serialize the target. Thevalueargument will typically be a model instance.If you want to implement a read-write relational field, you must also implement the
.to_internal_value(self, data)method.Example
For, example, we could define a relational field, to serialize a track to a custom string representation, using its ordering, title, and duration.
import time class TrackListingField(serializers.RelatedField): - def to_native(self, value): + def to_representation(self, value): duration = time.strftime('%M:%S', time.gmtime(value.duration)) return 'Track %d: %s (%s)' % (value.order, value.name, duration) @@ -688,6 +721,11 @@ class AlbumSerializer(serializers.ModelSerializer):
Further notes
+The
+querysetargumentThe
+querysetargument is only ever required for writable relationship field, in which case it is used for performing the model instance lookup, that maps from the primitive user input, into a model instance.In version 2.x a serializer class could sometimes automatically determine the
+querysetargument if aModelSerializerclass was being used.This behavior is now replaced with always using an explicit
+querysetargument for writable relational fields.Doing so reduces the amount of hidden 'magic' that
ModelSerializerprovides, makes the behavior of the field more clear, and ensures that it is trivial to move between using theModelSerializershortcut, or using fully explicitSerializerclasses.Reverse relations
Note that reverse relationships are not automatically included by the
ModelSerializerandHyperlinkedModelSerializerclasses. To include a reverse relationship, you must explicitly add it to the fields list. For example:-class AlbumSerializer(serializers.ModelSerializer): @@ -744,7 +782,7 @@ class Note(models.Model): 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. """ @@ -754,8 +792,8 @@ class Note(models.Model): return 'Note: ' + value.text 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:def to_native(self, value): +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_representation(self, value): """ Serialize bookmark instances using a bookmark serializer, and note instances using a note serializer. @@ -800,20 +838,6 @@ attributes are not configured to correctly match the URL conf. return queryset.get(account=account, slug=slug)
-Deprecated APIs
-The following classes have been deprecated, in favor of the
-many=<bool>syntax. -They continue to function, but their usage will raise aPendingDeprecationWarning, which is silent by default.-
-- -
ManyRelatedField- -
ManyPrimaryKeyRelatedField- -
ManyHyperlinkedRelatedField- -
ManySlugRelatedFieldThe
-null=<bool>flag has been deprecated in favor of therequired=<bool>flag. It will continue to function, but will raise aPendingDeprecationWarning.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.
-
Third Party Packages
The following third party packages are also available.
DRF Nested Routers
@@ -832,7 +856,7 @@ In the 2.4 release, these parts of the API will be removed entirely. -- cgit v1.2.3