aboutsummaryrefslogtreecommitdiffstats
path: root/rest_framework
diff options
context:
space:
mode:
authorTom Christie2013-06-02 19:50:24 +0100
committerTom Christie2013-06-02 19:50:24 +0100
commit8b73dce51da9f87940a6c18aef31020ba7ee14aa (patch)
tree4f4c164c6106357a745109576bf78a0d841c0518 /rest_framework
parent363b342548a41bfdcc3358595cd9d1de288c4962 (diff)
downloaddjango-rest-framework-8b73dce51da9f87940a6c18aef31020ba7ee14aa.tar.bz2
view_name argument to HyperlinkedModelSerializer is now properly enforced. Closes #471
Diffstat (limited to 'rest_framework')
-rw-r--r--rest_framework/relations.py16
-rw-r--r--rest_framework/serializers.py15
2 files changed, 20 insertions, 11 deletions
diff --git a/rest_framework/relations.py b/rest_framework/relations.py
index 4ecf795c..e3675b51 100644
--- a/rest_framework/relations.py
+++ b/rest_framework/relations.py
@@ -72,7 +72,6 @@ class RelatedField(WritableField):
else: # Reverse
self.queryset = manager.field.rel.to._default_manager.all()
except Exception:
- raise
msg = ('Serializer related fields must include a `queryset`' +
' argument or set `read_only=True')
raise Exception(msg)
@@ -488,14 +487,15 @@ class HyperlinkedIdentityField(Field):
slug_url_kwarg = None # Defaults to same as `slug_field` unless overridden
def __init__(self, *args, **kwargs):
- # TODO: Make view_name mandatory, and have the
- # HyperlinkedModelSerializer set it on-the-fly
- self.view_name = kwargs.pop('view_name', None)
- # Optionally the format of the target hyperlink may be specified
+ try:
+ self.view_name = kwargs.pop('view_name')
+ except KeyError:
+ msg = "HyperlinkedIdentityField requires 'view_name' argument"
+ raise ValueError(msg)
+
self.format = kwargs.pop('format', None)
lookup_field = kwargs.pop('lookup_field', None)
- if lookup_field is not None:
- self.lookup_field = lookup_field
+ self.lookup_field = lookup_field or self.lookup_field
# These are pending deprecation
if 'pk_url_kwarg' in kwargs:
@@ -518,7 +518,7 @@ class HyperlinkedIdentityField(Field):
def field_to_native(self, obj, field_name):
request = self.context.get('request', None)
format = self.context.get('format', None)
- view_name = self.view_name or self.parent.opts.view_name
+ view_name = self.view_name
if request is None:
warnings.warn("Using `HyperlinkedIdentityField` without including the "
diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py
index 4dde0d7c..a4969f60 100644
--- a/rest_framework/serializers.py
+++ b/rest_framework/serializers.py
@@ -903,15 +903,24 @@ class HyperlinkedModelSerializer(ModelSerializer):
_default_view_name = '%(model_name)s-detail'
_hyperlink_field_class = HyperlinkedRelatedField
- url = HyperlinkedIdentityField()
+ # 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)
- lookup_field = self.opts.lookup_field
- self.fields['url'] = HyperlinkedIdentityField(lookup_field=lookup_field)
+
if self.opts.view_name is None:
self.opts.view_name = self._get_default_view_name(self.opts.model)
+ 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
+
def _get_default_view_name(self, model):
"""
Return the view name to use if 'view_name' is not specified in 'Meta'