mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-23 01:57:00 +03:00
HyperlinkedModelSerializer supports overriding of 'url' field. Closes #936
This commit is contained in:
parent
a7a9e87284
commit
4ad1094968
|
@ -904,34 +904,20 @@ class HyperlinkedModelSerializer(ModelSerializer):
|
|||
_default_view_name = '%(model_name)s-detail'
|
||||
_hyperlink_field_class = HyperlinkedRelatedField
|
||||
|
||||
# Just a placeholder to ensure 'url' is the first field
|
||||
# The field itself is actually created on initialization,
|
||||
# when the view_name and lookup_field arguments are available.
|
||||
url = Field()
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(HyperlinkedModelSerializer, self).__init__(*args, **kwargs)
|
||||
def get_default_fields(self):
|
||||
fields = super(HyperlinkedModelSerializer, self).get_default_fields()
|
||||
|
||||
if self.opts.view_name is None:
|
||||
self.opts.view_name = self._get_default_view_name(self.opts.model)
|
||||
|
||||
if 'url' not in fields:
|
||||
url_field = HyperlinkedIdentityField(
|
||||
view_name=self.opts.view_name,
|
||||
lookup_field=self.opts.lookup_field
|
||||
)
|
||||
url_field.initialize(self, 'url')
|
||||
self.fields['url'] = url_field
|
||||
fields.insert(0, 'url', url_field)
|
||||
|
||||
def _get_default_view_name(self, model):
|
||||
"""
|
||||
Return the view name to use if 'view_name' is not specified in 'Meta'
|
||||
"""
|
||||
model_meta = model._meta
|
||||
format_kwargs = {
|
||||
'app_label': model_meta.app_label,
|
||||
'model_name': model_meta.object_name.lower()
|
||||
}
|
||||
return self._default_view_name % format_kwargs
|
||||
return fields
|
||||
|
||||
def get_pk_field(self, model_field):
|
||||
if self.opts.fields and model_field.name in self.opts.fields:
|
||||
|
@ -966,3 +952,14 @@ class HyperlinkedModelSerializer(ModelSerializer):
|
|||
return data.get('url', None)
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
def _get_default_view_name(self, model):
|
||||
"""
|
||||
Return the view name to use if 'view_name' is not specified in 'Meta'
|
||||
"""
|
||||
model_meta = model._meta
|
||||
format_kwargs = {
|
||||
'app_label': model_meta.app_label,
|
||||
'model_name': model_meta.object_name.lower()
|
||||
}
|
||||
return self._default_view_name % format_kwargs
|
||||
|
|
|
@ -301,3 +301,30 @@ class TestOptionalRelationHyperlinkedView(TestCase):
|
|||
data=json.dumps(self.data),
|
||||
content_type='application/json')
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
|
||||
|
||||
class TestOverriddenURLField(TestCase):
|
||||
def setUp(self):
|
||||
class OverriddenURLSerializer(serializers.HyperlinkedModelSerializer):
|
||||
url = serializers.SerializerMethodField('get_url')
|
||||
|
||||
class Meta:
|
||||
model = BlogPost
|
||||
fields = ('title', 'url')
|
||||
|
||||
def get_url(self, obj):
|
||||
return 'foo bar'
|
||||
|
||||
self.Serializer = OverriddenURLSerializer
|
||||
self.obj = BlogPost.objects.create(title='New blog post')
|
||||
|
||||
def test_overridden_url_field(self):
|
||||
"""
|
||||
The 'url' field should respect overriding.
|
||||
Regression test for #936.
|
||||
"""
|
||||
serializer = self.Serializer(self.obj)
|
||||
self.assertEqual(
|
||||
serializer.data,
|
||||
{'title': 'New blog post', 'url': 'foo bar'}
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue
Block a user