aboutsummaryrefslogtreecommitdiffstats
path: root/rest_framework
diff options
context:
space:
mode:
authorTom Christie2013-09-26 16:09:31 +0100
committerTom Christie2013-09-26 16:09:31 +0100
commit1fd83adb9c1f888ed05d5b6d570b5e37996f96ba (patch)
tree35fef6873d7c643aea1deb7cc903b179662eed4d /rest_framework
parent75d6446c8799763dccde0f5f03fbcae39c18dc7f (diff)
parent57a51f790bdff6c1cf34f3c6d64b0bef3033d89e (diff)
downloaddjango-rest-framework-1fd83adb9c1f888ed05d5b6d570b5e37996f96ba.tar.bz2
Merge branch 'master' of https://github.com/tomchristie/django-rest-framework
Diffstat (limited to 'rest_framework')
-rw-r--r--rest_framework/compat.py8
-rw-r--r--rest_framework/filters.py4
-rw-r--r--rest_framework/permissions.py7
-rw-r--r--rest_framework/serializers.py3
-rw-r--r--rest_framework/tests/test_permissions.py4
-rw-r--r--rest_framework/tests/test_serializer.py16
6 files changed, 35 insertions, 7 deletions
diff --git a/rest_framework/compat.py b/rest_framework/compat.py
index b9d1dae6..581e29fc 100644
--- a/rest_framework/compat.py
+++ b/rest_framework/compat.py
@@ -80,6 +80,14 @@ except ImportError:
Image = None
+def get_model_name(model_cls):
+ try:
+ return model_cls._meta.model_name
+ except AttributeError:
+ # < 1.6 used module_name instead of model_name
+ return model_cls._meta.module_name
+
+
def get_concrete_model(model_cls):
try:
return model_cls._meta.concrete_model
diff --git a/rest_framework/filters.py b/rest_framework/filters.py
index b8fe7f77..e287a168 100644
--- a/rest_framework/filters.py
+++ b/rest_framework/filters.py
@@ -4,7 +4,7 @@ returned by list views.
"""
from __future__ import unicode_literals
from django.db import models
-from rest_framework.compat import django_filters, six, guardian
+from rest_framework.compat import django_filters, six, guardian, get_model_name
from functools import reduce
import operator
@@ -158,7 +158,7 @@ class DjangoObjectPermissionsFilter(BaseFilterBackend):
model_cls = queryset.model
kwargs = {
'app_label': model_cls._meta.app_label,
- 'model_name': model_cls._meta.module_name
+ 'model_name': get_model_name(model_cls)
}
permission = self.perm_format % kwargs
return guardian.shortcuts.get_objects_for_user(user, permission, queryset)
diff --git a/rest_framework/permissions.py b/rest_framework/permissions.py
index 53184798..ab6655e7 100644
--- a/rest_framework/permissions.py
+++ b/rest_framework/permissions.py
@@ -8,7 +8,8 @@ import warnings
SAFE_METHODS = ['GET', 'HEAD', 'OPTIONS']
from django.http import Http404
-from rest_framework.compat import oauth2_provider_scope, oauth2_constants
+from rest_framework.compat import (get_model_name, oauth2_provider_scope,
+ oauth2_constants)
class BasePermission(object):
@@ -116,7 +117,7 @@ class DjangoModelPermissions(BasePermission):
"""
kwargs = {
'app_label': model_cls._meta.app_label,
- 'model_name': model_cls._meta.module_name
+ 'model_name': get_model_name(model_cls)
}
return [perm % kwargs for perm in self.perms_map[method]]
@@ -177,7 +178,7 @@ class DjangoObjectPermissions(DjangoModelPermissions):
def get_required_object_permissions(self, method, model_cls):
kwargs = {
'app_label': model_cls._meta.app_label,
- 'model_name': model_cls._meta.module_name
+ 'model_name': get_model_name(model_cls)
}
return [perm % kwargs for perm in self.perms_map[method]]
diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py
index a63c7f6c..8d2e0feb 100644
--- a/rest_framework/serializers.py
+++ b/rest_framework/serializers.py
@@ -518,6 +518,9 @@ class BaseSerializer(WritableField):
"""
Save the deserialized object and return it.
"""
+ # Clear cached _data, which may be invalidated by `save()`
+ self._data = None
+
if isinstance(self.object, list):
[self.save_object(item, **kwargs) for item in self.object]
diff --git a/rest_framework/tests/test_permissions.py b/rest_framework/tests/test_permissions.py
index d08124f4..6e3a6303 100644
--- a/rest_framework/tests/test_permissions.py
+++ b/rest_framework/tests/test_permissions.py
@@ -4,7 +4,7 @@ from django.db import models
from django.test import TestCase
from django.utils import unittest
from rest_framework import generics, status, permissions, authentication, HTTP_HEADER_ENCODING
-from rest_framework.compat import guardian
+from rest_framework.compat import guardian, get_model_name
from rest_framework.filters import DjangoObjectPermissionsFilter
from rest_framework.test import APIRequestFactory
from rest_framework.tests.models import BasicModel
@@ -202,7 +202,7 @@ class ObjectPermissionsIntegrationTests(TestCase):
# give everyone model level permissions, as we are not testing those
everyone = Group.objects.create(name='everyone')
- model_name = BasicPermModel._meta.module_name
+ model_name = get_model_name(BasicPermModel)
app_label = BasicPermModel._meta.app_label
f = '{0}_{1}'.format
perms = {
diff --git a/rest_framework/tests/test_serializer.py b/rest_framework/tests/test_serializer.py
index c2497660..8d246b01 100644
--- a/rest_framework/tests/test_serializer.py
+++ b/rest_framework/tests/test_serializer.py
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models
from django.db.models.fields import BLANK_CHOICE_DASH
@@ -136,6 +137,7 @@ class BasicTests(TestCase):
'Happy new year!',
datetime.datetime(2012, 1, 1)
)
+ self.actionitem = ActionItem(title='Some to do item',)
self.data = {
'email': 'tom@example.com',
'content': 'Happy new year!',
@@ -264,6 +266,20 @@ class BasicTests(TestCase):
"""
self.assertRaises(AssertionError, PersonSerializerInvalidReadOnly, [])
+ def test_serializer_data_is_cleared_on_save(self):
+ """
+ Check _data attribute is cleared on `save()`
+
+ Regression test for #1116
+ — id field is not populated if `data` is accessed prior to `save()`
+ """
+ serializer = ActionItemSerializer(self.actionitem)
+ self.assertIsNone(serializer.data.get('id',None), 'New instance. `id` should not be set.')
+ serializer.save()
+ self.assertIsNotNone(serializer.data.get('id',None), 'Model is saved. `id` should be set.')
+
+
+
class DictStyleSerializer(serializers.Serializer):
"""