mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-10 19:56:59 +03:00
Allow relative style hyperlinked URLs
This commit is contained in:
parent
9c996d7d2a
commit
75751cc64e
|
@ -678,6 +678,25 @@ You can explicitly include the primary key by adding it to the `fields` option,
|
||||||
model = Account
|
model = Account
|
||||||
fields = ('url', 'id', 'account_name', 'users', 'created')
|
fields = ('url', 'id', 'account_name', 'users', 'created')
|
||||||
|
|
||||||
|
## Absolute and relative URLs
|
||||||
|
|
||||||
|
When instantiating a `HyperlinkedModelSerializer` you must include the current
|
||||||
|
`request` in the serializer context, for example:
|
||||||
|
|
||||||
|
serializer = AccountSerializer(queryset, context={'request': request})
|
||||||
|
|
||||||
|
Doing so will ensure that the hyperlinks can include an appropriate hostname,
|
||||||
|
so that the resulting representation uses fully qualified URLs, such as:
|
||||||
|
|
||||||
|
http://api.example.com/accounts/1/
|
||||||
|
|
||||||
|
Rather than relative URLs, such as:
|
||||||
|
|
||||||
|
/accounts/1/
|
||||||
|
|
||||||
|
If you *do* want to use relative URLs, you should explicitly pass `{'request': None}`
|
||||||
|
in the serializer context.
|
||||||
|
|
||||||
## How hyperlinked views are determined
|
## How hyperlinked views are determined
|
||||||
|
|
||||||
There needs to be a way of determining which views should be used for hyperlinking to model instances.
|
There needs to be a way of determining which views should be used for hyperlinking to model instances.
|
||||||
|
|
|
@ -325,15 +325,15 @@ class HyperlinkedRelatedField(RelatedField):
|
||||||
self.fail('does_not_exist')
|
self.fail('does_not_exist')
|
||||||
|
|
||||||
def to_representation(self, value):
|
def to_representation(self, value):
|
||||||
request = self.context.get('request', None)
|
assert 'request' in self.context, (
|
||||||
format = self.context.get('format', None)
|
|
||||||
|
|
||||||
assert request is not None, (
|
|
||||||
"`%s` requires the request in the serializer"
|
"`%s` requires the request in the serializer"
|
||||||
" context. Add `context={'request': request}` when instantiating "
|
" context. Add `context={'request': request}` when instantiating "
|
||||||
"the serializer." % self.__class__.__name__
|
"the serializer." % self.__class__.__name__
|
||||||
)
|
)
|
||||||
|
|
||||||
|
request = self.context['request']
|
||||||
|
format = self.context.get('format', None)
|
||||||
|
|
||||||
# By default use whatever format is given for the current context
|
# By default use whatever format is given for the current context
|
||||||
# unless the target is a different type to the source.
|
# unless the target is a different type to the source.
|
||||||
#
|
#
|
||||||
|
|
|
@ -82,6 +82,17 @@ class HyperlinkedManyToManyTests(TestCase):
|
||||||
for target in ManyToManyTarget.objects.all():
|
for target in ManyToManyTarget.objects.all():
|
||||||
source.targets.add(target)
|
source.targets.add(target)
|
||||||
|
|
||||||
|
def test_relative_hyperlinks(self):
|
||||||
|
queryset = ManyToManySource.objects.all()
|
||||||
|
serializer = ManyToManySourceSerializer(queryset, many=True, context={'request': None})
|
||||||
|
expected = [
|
||||||
|
{'url': '/manytomanysource/1/', 'name': 'source-1', 'targets': ['/manytomanytarget/1/']},
|
||||||
|
{'url': '/manytomanysource/2/', 'name': 'source-2', 'targets': ['/manytomanytarget/1/', '/manytomanytarget/2/']},
|
||||||
|
{'url': '/manytomanysource/3/', 'name': 'source-3', 'targets': ['/manytomanytarget/1/', '/manytomanytarget/2/', '/manytomanytarget/3/']}
|
||||||
|
]
|
||||||
|
with self.assertNumQueries(4):
|
||||||
|
self.assertEqual(serializer.data, expected)
|
||||||
|
|
||||||
def test_many_to_many_retrieve(self):
|
def test_many_to_many_retrieve(self):
|
||||||
queryset = ManyToManySource.objects.all()
|
queryset = ManyToManySource.objects.all()
|
||||||
serializer = ManyToManySourceSerializer(queryset, many=True, context={'request': request})
|
serializer = ManyToManySourceSerializer(queryset, many=True, context={'request': request})
|
||||||
|
|
Loading…
Reference in New Issue
Block a user