aboutsummaryrefslogtreecommitdiffstats
path: root/docs/api-guide/relations.md
diff options
context:
space:
mode:
authorTom Christie2013-05-01 09:03:09 +0100
committerTom Christie2013-05-01 09:03:09 +0100
commit35f99cddc4a098547389fab7d9f397ad442dfff1 (patch)
treeffe646aff07d2746355fa824033099416eba0ccf /docs/api-guide/relations.md
parent22af28d146f2c4caccafafc78603ce20ffd76425 (diff)
downloaddjango-rest-framework-35f99cddc4a098547389fab7d9f397ad442dfff1.tar.bz2
lookup_field on hyperlinked fields, and overriddable hyperlinked fields. Closes #688
Diffstat (limited to 'docs/api-guide/relations.md')
-rw-r--r--docs/api-guide/relations.md67
1 files changed, 45 insertions, 22 deletions
diff --git a/docs/api-guide/relations.md b/docs/api-guide/relations.md
index 623fe1a9..756e1562 100644
--- a/docs/api-guide/relations.md
+++ b/docs/api-guide/relations.md
@@ -123,9 +123,9 @@ Would serialize to a representation like this:
'album_name': 'Graceland',
'artist': 'Paul Simon'
'tracks': [
- 'http://www.example.com/api/tracks/45',
- 'http://www.example.com/api/tracks/46',
- 'http://www.example.com/api/tracks/47',
+ 'http://www.example.com/api/tracks/45/',
+ 'http://www.example.com/api/tracks/46/',
+ 'http://www.example.com/api/tracks/47/',
...
]
}
@@ -138,9 +138,7 @@ By default this field is read-write, although you can change this behavior using
* `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.
* `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`.
-* `slug_field` - The field on the target that should be used for the lookup. Default is `'slug'`.
-* `pk_url_kwarg` - The named url parameter for the pk field lookup. Default is `pk`.
-* `slug_url_kwarg` - The named url parameter for the slug field lookup. Default is to use the same value as given for `slug_field`.
+* `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'`.
* `format` - If using format suffixes, hyperlinked fields will use the same format suffix for the target unless overridden by using the `format` argument.
## SlugRelatedField
@@ -196,7 +194,7 @@ Would serialize to a representation like this:
{
'album_name': 'The Eraser',
'artist': 'Thom Yorke'
- 'track_listing': 'http://www.example.com/api/track_list/12',
+ 'track_listing': 'http://www.example.com/api/track_list/12/',
}
This field is always read-only.
@@ -291,32 +289,23 @@ This custom field would then serialize to the following representation.
## Reverse relations
-Note that reverse relationships are not automatically generated by the `ModelSerializer` and `HyperlinkedModelSerializer` classes. To include a reverse relationship, you cannot simply add it to the fields list.
-
-**The following will not work:**
+Note that reverse relationships are not automatically included by the `ModelSerializer` and `HyperlinkedModelSerializer` classes. To include a reverse relationship, you must explicitly add it to the fields list. For example:
class AlbumSerializer(serializers.ModelSerializer):
class Meta:
- fields = ('tracks', ...)
-
-Instead, you must explicitly add it to the serializer. For example:
-
- class AlbumSerializer(serializers.ModelSerializer):
- tracks = serializers.PrimaryKeyRelatedField(many=True)
- ...
-
-By default, the field will uses the same accessor as it's field name to retrieve the relationship, so in this example, `Album` instances would need to have the `tracks` attribute for this relationship to work.
+ fields = ('tracks', ...)
-The best way to ensure this is typically to make sure that the relationship on the model definition has it's `related_name` argument properly set. For example:
+You'll normally want to ensure that you've set an appropriate `related_name` argument on the relationship, that you can use as the field name. For example:
class Track(models.Model):
album = models.ForeignKey(Album, related_name='tracks')
...
-Alternatively, you can use the `source` argument on the serializer field, to use a different accessor attribute than the field name. For example.
+If you have not set a related name for the reverse relationship, you'll need to use the automatically generated related name in the `fields` argument. For example:
class AlbumSerializer(serializers.ModelSerializer):
- tracks = serializers.PrimaryKeyRelatedField(many=True, source='track_set')
+ class Meta:
+ fields = ('track_set', ...)
See the Django documentation on [reverse relationships][reverse-relationships] for more details.
@@ -394,6 +383,40 @@ Note that reverse generic keys, expressed using the `GenericRelation` field, can
For more information see [the Django documentation on generic relations][generic-relations].
+## Advanced Hyperlinked fields
+
+If you have very specific requirements for the style of your hyperlinked relationships you can override `HyperlinkedRelatedField`.
+
+There are two methods you'll need to override.
+
+#### get_url(self, obj, view_name, request, format)
+
+This method should return the URL that corresponds to the given object.
+
+May raise a `NoReverseMatch` if the `view_name` and `lookup_field`
+attributes are not configured to correctly match the URL conf.
+
+#### get_object(self, queryset, view_name, view_args, view_kwargs)
+
+
+This method should the object that corresponds to the matched URL conf arguments.
+
+May raise an `ObjectDoesNotExist` exception.
+
+### Example
+
+For example, if all your object URLs used both a account and a slug in the the URL to reference the object, you might create a custom field like this:
+
+ class CustomHyperlinkedField(serializers.HyperlinkedRelatedField):
+ def get_url(self, obj, view_name, request, format):
+ kwargs = {'account': obj.account, 'slug': obj.slug}
+ return reverse(view_name, kwargs=kwargs, request=request, format=format)
+
+ def get_object(self, queryset, view_name, view_args, view_kwargs):
+ account = view_kwargs['account']
+ slug = view_kwargs['slug']
+ return queryset.get(account=account, slug=sug)
+
---
## Deprecated APIs