aboutsummaryrefslogtreecommitdiffstats
path: root/rest_framework
diff options
context:
space:
mode:
Diffstat (limited to 'rest_framework')
-rw-r--r--rest_framework/fields.py19
-rw-r--r--rest_framework/serializers.py10
-rw-r--r--rest_framework/tests/hyperlinkedserializers.py11
-rw-r--r--rest_framework/tests/pk_relations.py2
4 files changed, 29 insertions, 13 deletions
diff --git a/rest_framework/fields.py b/rest_framework/fields.py
index eb4c5e1f..dc726a32 100644
--- a/rest_framework/fields.py
+++ b/rest_framework/fields.py
@@ -40,7 +40,7 @@ class Field(object):
self.source = source
- def initialize(self, parent):
+ def initialize(self, parent, field_name):
"""
Called to set up a field prior to field_to_native or field_from_native.
@@ -248,7 +248,22 @@ class RelatedField(WritableField):
def __init__(self, *args, **kwargs):
self.queryset = kwargs.pop('queryset', None)
super(RelatedField, self).__init__(*args, **kwargs)
- self.read_only = self.default_read_only
+ self.read_only = kwargs.pop('read_only', self.default_read_only)
+
+ def initialize(self, parent, field_name):
+ super(RelatedField, self).initialize(parent, field_name)
+ if self.queryset is None and not self.read_only:
+ try:
+ manager = getattr(self.parent.opts.model, self.source or field_name)
+ if hasattr(manager, 'related'): # Forward
+ self.queryset = manager.related.model._default_manager.all()
+ else: # Reverse
+ self.queryset = manager.field.rel.to._default_manager.all()
+ except:
+ raise
+ msg = ('Serializer related fields must include a `queryset`' +
+ ' argument or set `read_only=True')
+ raise Exception(msg)
### We need this stuff to make form choices work...
diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py
index 08f0a6a8..05795ae7 100644
--- a/rest_framework/serializers.py
+++ b/rest_framework/serializers.py
@@ -93,8 +93,8 @@ class BaseSerializer(Field):
def __init__(self, instance=None, data=None, context=None, **kwargs):
super(BaseSerializer, self).__init__(**kwargs)
- self.fields = copy.deepcopy(self.base_fields)
self.opts = self._options_class(self.Meta)
+ self.fields = copy.deepcopy(self.base_fields)
self.parent = None
self.root = None
@@ -128,7 +128,7 @@ class BaseSerializer(Field):
for key, field in self.fields.items():
ret[key] = field
# Set up the field
- field.initialize(parent=self)
+ field.initialize(parent=self, field_name=key)
# Add in the default fields
fields = self.default_fields(nested)
@@ -153,12 +153,12 @@ class BaseSerializer(Field):
#####
# Field methods - used when the serializer class is itself used as a field.
- def initialize(self, parent):
+ def initialize(self, parent, field_name):
"""
Same behaviour as usual Field, except that we need to keep track
of state so that we can deal with handling maximum depth.
"""
- super(BaseSerializer, self).initialize(parent)
+ super(BaseSerializer, self).initialize(parent, field_name)
if parent.opts.depth:
self.opts.depth = parent.opts.depth - 1
@@ -369,7 +369,7 @@ class ModelSerializer(Serializer):
field = self.get_field(model_field)
if field:
- field.initialize(parent=self)
+ field.initialize(parent=self, field_name=model_field.name)
ret[model_field.name] = field
return ret
diff --git a/rest_framework/tests/hyperlinkedserializers.py b/rest_framework/tests/hyperlinkedserializers.py
index 92c3691e..147943c6 100644
--- a/rest_framework/tests/hyperlinkedserializers.py
+++ b/rest_framework/tests/hyperlinkedserializers.py
@@ -7,12 +7,13 @@ from rest_framework.tests.models import Anchor, BasicModel, ManyToManyModel, Blo
factory = RequestFactory()
-class BlogPostCommentSerializer(serializers.Serializer):
+class BlogPostCommentSerializer(serializers.ModelSerializer):
text = serializers.CharField()
- blog_post_url = serializers.HyperlinkedRelatedField(source='blog_post', view_name='blogpost-detail', queryset=BlogPost.objects.all())
+ blog_post_url = serializers.HyperlinkedRelatedField(source='blog_post', view_name='blogpost-detail')
- def restore_object(self, attrs, instance=None):
- return BlogPostComment(**attrs)
+ class Meta:
+ model = BlogPostComment
+ fields = ('text', 'blog_post_url')
class BasicList(generics.ListCreateAPIView):
@@ -42,7 +43,7 @@ class ManyToManyDetail(generics.RetrieveAPIView):
class BlogPostCommentListCreate(generics.ListCreateAPIView):
model = BlogPostComment
- model_serializer_class = BlogPostCommentSerializer
+ serializer_class = BlogPostCommentSerializer
class BlogPostDetail(generics.RetrieveAPIView):
diff --git a/rest_framework/tests/pk_relations.py b/rest_framework/tests/pk_relations.py
index 89f53316..94709810 100644
--- a/rest_framework/tests/pk_relations.py
+++ b/rest_framework/tests/pk_relations.py
@@ -15,7 +15,7 @@ class ManyToManySource(models.Model):
class ManyToManyTargetSerializer(serializers.ModelSerializer):
- sources = serializers.ManyPrimaryKeyRelatedField(queryset=ManyToManySource.objects.all())
+ sources = serializers.ManyPrimaryKeyRelatedField()
class Meta:
model = ManyToManyTarget