diff options
| author | Tom Christie | 2013-05-01 09:03:09 +0100 |
|---|---|---|
| committer | Tom Christie | 2013-05-01 09:03:09 +0100 |
| commit | 35f99cddc4a098547389fab7d9f397ad442dfff1 (patch) | |
| tree | ffe646aff07d2746355fa824033099416eba0ccf /docs/api-guide/relations.md | |
| parent | 22af28d146f2c4caccafafc78603ce20ffd76425 (diff) | |
| download | django-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.md | 67 |
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 |
