aboutsummaryrefslogtreecommitdiffstats
path: root/rest_framework
diff options
context:
space:
mode:
Diffstat (limited to 'rest_framework')
-rw-r--r--rest_framework/permissions.py13
-rw-r--r--rest_framework/relations.py1
-rw-r--r--rest_framework/serializers.py14
-rw-r--r--rest_framework/tests/relations_pk.py6
4 files changed, 22 insertions, 12 deletions
diff --git a/rest_framework/permissions.py b/rest_framework/permissions.py
index c477474c..92f8215a 100644
--- a/rest_framework/permissions.py
+++ b/rest_framework/permissions.py
@@ -104,6 +104,8 @@ class DjangoModelPermissions(BasePermission):
'DELETE': ['%(app_label)s.delete_%(model_name)s'],
}
+ authenticated_users_only = True
+
def get_required_permissions(self, method, model_cls):
"""
Given a model and an HTTP method, return the list of permission
@@ -117,13 +119,18 @@ class DjangoModelPermissions(BasePermission):
def has_permission(self, request, view):
model_cls = getattr(view, 'model', None)
- if not model_cls:
- return True
+ queryset = getattr(view, 'queryset', None)
+
+ if model_cls is None and queryset is not None:
+ model_cls = queryset.model
+
+ assert model_cls, ('Cannot apply DjangoModelPermissions on a view that'
+ ' does not have `.model` or `.queryset` property.')
perms = self.get_required_permissions(request.method, model_cls)
if (request.user and
- request.user.is_authenticated() and
+ (request.user.is_authenticated() or not self.authenticated_users_only) and
request.user.has_perms(perms)):
return True
return False
diff --git a/rest_framework/relations.py b/rest_framework/relations.py
index 0c108717..2a10e9af 100644
--- a/rest_framework/relations.py
+++ b/rest_framework/relations.py
@@ -235,7 +235,6 @@ class PrimaryKeyRelatedField(RelatedField):
pk = getattr(obj, self.source or field_name).pk
except ObjectDoesNotExist:
return None
- return self.to_native(obj.pk)
# Forward relationship
return self.to_native(pk)
diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py
index 106e3f17..2ae7c215 100644
--- a/rest_framework/serializers.py
+++ b/rest_framework/serializers.py
@@ -391,11 +391,17 @@ class BaseSerializer(Field):
return self._data
+ def save_object(self, obj):
+ obj.save()
+
def save(self):
"""
Save the deserialized object and return it.
"""
- self.object.save()
+ if isinstance(self.object, list):
+ [self.save_object(item) for item in self.object]
+ else:
+ self.save_object(self.object)
return self.object
@@ -612,11 +618,11 @@ class ModelSerializer(Serializer):
if instance:
return self.full_clean(instance)
- def save(self):
+ def save_object(self, obj):
"""
Save the deserialized object and return it.
"""
- self.object.save()
+ obj.save()
if getattr(self, 'm2m_data', None):
for accessor_name, object_list in self.m2m_data.items():
@@ -628,8 +634,6 @@ class ModelSerializer(Serializer):
setattr(self.object, accessor_name, object_list)
self.related_data = {}
- return self.object
-
class HyperlinkedModelSerializerOptions(ModelSerializerOptions):
"""
diff --git a/rest_framework/tests/relations_pk.py b/rest_framework/tests/relations_pk.py
index d6ae3176..f08e1808 100644
--- a/rest_framework/tests/relations_pk.py
+++ b/rest_framework/tests/relations_pk.py
@@ -407,14 +407,14 @@ class PKNullableOneToOneTests(TestCase):
target.save()
new_target = OneToOneTarget(name='target-2')
new_target.save()
- source = NullableOneToOneSource(name='source-1', target=target)
+ source = NullableOneToOneSource(name='source-1', target=new_target)
source.save()
def test_reverse_foreign_key_retrieve_with_null(self):
queryset = OneToOneTarget.objects.all()
serializer = NullableOneToOneTargetSerializer(queryset, many=True)
expected = [
- {'id': 1, 'name': 'target-1', 'nullable_source': 1},
- {'id': 2, 'name': 'target-2', 'nullable_source': None},
+ {'id': 1, 'name': 'target-1', 'nullable_source': None},
+ {'id': 2, 'name': 'target-2', 'nullable_source': 1},
]
self.assertEqual(serializer.data, expected)