Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Fix Django 1.10 to-many deprecation
  • Loading branch information
Ryan P Kilby committed Sep 15, 2016
commit 8609c9ca8c0d9c747d594d2b4f5cc7cc8be98f0a
8 changes: 8 additions & 0 deletions rest_framework/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,3 +277,11 @@ def template_render(template, context=None, request=None):
# backends template, e.g. django.template.backends.django.Template
else:
return template.render(context, request=request)


def set_many(instance, field, value):
if django.VERSION < (1, 10):
setattr(instance, field, value)
else:
field = getattr(instance, field)
field.set(value)
10 changes: 7 additions & 3 deletions rest_framework/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from django.utils.translation import ugettext_lazy as _

from rest_framework.compat import JSONField as ModelJSONField
from rest_framework.compat import postgres_fields, unicode_to_repr
from rest_framework.compat import postgres_fields, set_many, unicode_to_repr
from rest_framework.utils import model_meta
from rest_framework.utils.field_mapping import (
ClassLookupDict, get_field_kwargs, get_nested_relation_kwargs,
Expand Down Expand Up @@ -892,19 +892,23 @@ def create(self, validated_data):
# Save many-to-many relationships after the instance is created.
if many_to_many:
for field_name, value in many_to_many.items():
setattr(instance, field_name, value)
set_many(instance, field_name, value)

return instance

def update(self, instance, validated_data):
raise_errors_on_nested_writes('update', self, validated_data)
info = model_meta.get_field_info(instance)

# Simply set each attribute on the instance, and then save it.
# Note that unlike `.create()` we don't need to treat many-to-many
# relationships as being a special case. During updates we already
# have an instance pk for the relationships to be associated with.
for attr, value in validated_data.items():
setattr(instance, attr, value)
if attr in info.relations and info.relations[attr].to_many:
set_many(instance, attr, value)
else:
setattr(instance, attr, value)
instance.save()

return instance
Expand Down
4 changes: 2 additions & 2 deletions tests/test_model_serializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from django.utils import six

from rest_framework import serializers
from rest_framework.compat import unicode_repr
from rest_framework.compat import set_many, unicode_repr


def dedent(blocktext):
Expand Down Expand Up @@ -651,7 +651,7 @@ def setUp(self):
foreign_key=self.foreign_key_target,
one_to_one=self.one_to_one_target,
)
self.instance.many_to_many = self.many_to_many_targets
set_many(self.instance, 'many_to_many', self.many_to_many_targets)
self.instance.save()

def test_pk_retrival(self):
Expand Down
10 changes: 5 additions & 5 deletions tests/test_permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
HTTP_HEADER_ENCODING, authentication, generics, permissions, serializers,
status
)
from rest_framework.compat import guardian
from rest_framework.compat import guardian, set_many
from rest_framework.filters import DjangoObjectPermissionsFilter
from rest_framework.routers import DefaultRouter
from rest_framework.test import APIRequestFactory
Expand Down Expand Up @@ -74,15 +74,15 @@ class ModelPermissionsIntegrationTests(TestCase):
def setUp(self):
User.objects.create_user('disallowed', '[email protected]', 'password')
user = User.objects.create_user('permitted', '[email protected]', 'password')
user.user_permissions = [
set_many(user, 'user_permissions', [
Permission.objects.get(codename='add_basicmodel'),
Permission.objects.get(codename='change_basicmodel'),
Permission.objects.get(codename='delete_basicmodel')
]
])
user = User.objects.create_user('updateonly', '[email protected]', 'password')
user.user_permissions = [
set_many(user, 'user_permissions', [
Permission.objects.get(codename='change_basicmodel'),
]
])

self.permitted_credentials = basic_auth_header('permitted', 'password')
self.disallowed_credentials = basic_auth_header('disallowed', 'password')
Expand Down