mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-02-02 20:54:42 +03:00
queryset
argument is now optional on writable model fields.
This commit is contained in:
parent
ccd5f29510
commit
33be4b43b9
|
@ -64,6 +64,7 @@ To run the tests.
|
||||||
**Warning**: Please read [this thread][2.1.0-notes] regarding the `instance` and `data` keyword args before updating to 2.1.0.
|
**Warning**: Please read [this thread][2.1.0-notes] regarding the `instance` and `data` keyword args before updating to 2.1.0.
|
||||||
|
|
||||||
* **Serializer `instance` and `data` keyword args have their position swapped.**
|
* **Serializer `instance` and `data` keyword args have their position swapped.**
|
||||||
|
* `queryset` argument is now optional on writable model fields.
|
||||||
* Support Django's cache framework.
|
* Support Django's cache framework.
|
||||||
* Minor field improvements. (Don't stringify dicts, more robust many-pk fields.)
|
* Minor field improvements. (Don't stringify dicts, more robust many-pk fields.)
|
||||||
* Bugfixes (Support choice field in Browseable API)
|
* Bugfixes (Support choice field in Browseable API)
|
||||||
|
|
|
@ -11,9 +11,11 @@
|
||||||
**Warning**: Please read [this thread][2.1.0-notes] regarding the `instance` and `data` keyword args before updating to 2.1.0.
|
**Warning**: Please read [this thread][2.1.0-notes] regarding the `instance` and `data` keyword args before updating to 2.1.0.
|
||||||
|
|
||||||
* **Serializer `instance` and `data` keyword args have their position swapped.**
|
* **Serializer `instance` and `data` keyword args have their position swapped.**
|
||||||
|
* `queryset` argument is now optional on writable model fields.
|
||||||
* Support Django's cache framework.
|
* Support Django's cache framework.
|
||||||
* Minor field improvements. (Don't stringify dicts, more robust many-pk fields.)
|
* Minor field improvements. (Don't stringify dicts, more robust many-pk fields.)
|
||||||
* Bugfixes (Support choice field in Browseable API)
|
* Bugfix: Support choice field in Browseable API.
|
||||||
|
* Bugfix: Related fields with `read_only=True` do not require a `queryset` argument.
|
||||||
|
|
||||||
## 2.0.2
|
## 2.0.2
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ class Field(object):
|
||||||
|
|
||||||
self.source = source
|
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.
|
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):
|
def __init__(self, *args, **kwargs):
|
||||||
self.queryset = kwargs.pop('queryset', None)
|
self.queryset = kwargs.pop('queryset', None)
|
||||||
super(RelatedField, self).__init__(*args, **kwargs)
|
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...
|
### We need this stuff to make form choices work...
|
||||||
|
|
||||||
|
|
|
@ -93,8 +93,8 @@ class BaseSerializer(Field):
|
||||||
|
|
||||||
def __init__(self, instance=None, data=None, context=None, **kwargs):
|
def __init__(self, instance=None, data=None, context=None, **kwargs):
|
||||||
super(BaseSerializer, self).__init__(**kwargs)
|
super(BaseSerializer, self).__init__(**kwargs)
|
||||||
self.fields = copy.deepcopy(self.base_fields)
|
|
||||||
self.opts = self._options_class(self.Meta)
|
self.opts = self._options_class(self.Meta)
|
||||||
|
self.fields = copy.deepcopy(self.base_fields)
|
||||||
self.parent = None
|
self.parent = None
|
||||||
self.root = None
|
self.root = None
|
||||||
|
|
||||||
|
@ -128,7 +128,7 @@ class BaseSerializer(Field):
|
||||||
for key, field in self.fields.items():
|
for key, field in self.fields.items():
|
||||||
ret[key] = field
|
ret[key] = field
|
||||||
# Set up the field
|
# Set up the field
|
||||||
field.initialize(parent=self)
|
field.initialize(parent=self, field_name=key)
|
||||||
|
|
||||||
# Add in the default fields
|
# Add in the default fields
|
||||||
fields = self.default_fields(nested)
|
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.
|
# 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
|
Same behaviour as usual Field, except that we need to keep track
|
||||||
of state so that we can deal with handling maximum depth.
|
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:
|
if parent.opts.depth:
|
||||||
self.opts.depth = parent.opts.depth - 1
|
self.opts.depth = parent.opts.depth - 1
|
||||||
|
|
||||||
|
@ -369,7 +369,7 @@ class ModelSerializer(Serializer):
|
||||||
field = self.get_field(model_field)
|
field = self.get_field(model_field)
|
||||||
|
|
||||||
if field:
|
if field:
|
||||||
field.initialize(parent=self)
|
field.initialize(parent=self, field_name=model_field.name)
|
||||||
ret[model_field.name] = field
|
ret[model_field.name] = field
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
|
@ -7,12 +7,13 @@ from rest_framework.tests.models import Anchor, BasicModel, ManyToManyModel, Blo
|
||||||
factory = RequestFactory()
|
factory = RequestFactory()
|
||||||
|
|
||||||
|
|
||||||
class BlogPostCommentSerializer(serializers.Serializer):
|
class BlogPostCommentSerializer(serializers.ModelSerializer):
|
||||||
text = serializers.CharField()
|
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):
|
class Meta:
|
||||||
return BlogPostComment(**attrs)
|
model = BlogPostComment
|
||||||
|
fields = ('text', 'blog_post_url')
|
||||||
|
|
||||||
|
|
||||||
class BasicList(generics.ListCreateAPIView):
|
class BasicList(generics.ListCreateAPIView):
|
||||||
|
@ -42,7 +43,7 @@ class ManyToManyDetail(generics.RetrieveAPIView):
|
||||||
|
|
||||||
class BlogPostCommentListCreate(generics.ListCreateAPIView):
|
class BlogPostCommentListCreate(generics.ListCreateAPIView):
|
||||||
model = BlogPostComment
|
model = BlogPostComment
|
||||||
model_serializer_class = BlogPostCommentSerializer
|
serializer_class = BlogPostCommentSerializer
|
||||||
|
|
||||||
|
|
||||||
class BlogPostDetail(generics.RetrieveAPIView):
|
class BlogPostDetail(generics.RetrieveAPIView):
|
||||||
|
|
|
@ -15,7 +15,7 @@ class ManyToManySource(models.Model):
|
||||||
|
|
||||||
|
|
||||||
class ManyToManyTargetSerializer(serializers.ModelSerializer):
|
class ManyToManyTargetSerializer(serializers.ModelSerializer):
|
||||||
sources = serializers.ManyPrimaryKeyRelatedField(queryset=ManyToManySource.objects.all())
|
sources = serializers.ManyPrimaryKeyRelatedField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = ManyToManyTarget
|
model = ManyToManyTarget
|
||||||
|
|
Loading…
Reference in New Issue
Block a user