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 | |
| 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')
| -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 | 
