Tests for relational fields

This commit is contained in:
Tom Christie 2014-10-08 11:04:08 +01:00
parent 3fa4a1898a
commit 093febb912
4 changed files with 1008 additions and 995 deletions

View File

@ -1,7 +1,7 @@
from django import forms from django import forms
from django.conf import settings from django.conf import settings
from django.core import validators from django.core import validators
from django.core.exceptions import ValidationError from django.core.exceptions import ObjectDoesNotExist, ValidationError
from django.utils import six, timezone from django.utils import six, timezone
from django.utils.datastructures import SortedDict from django.utils.datastructures import SortedDict
from django.utils.dateparse import parse_date, parse_datetime, parse_time from django.utils.dateparse import parse_date, parse_datetime, parse_time
@ -54,6 +54,8 @@ def get_attribute(instance, attrs):
for attr in attrs: for attr in attrs:
try: try:
instance = getattr(instance, attr) instance = getattr(instance, attr)
except ObjectDoesNotExist:
return None
except AttributeError as exc: except AttributeError as exc:
try: try:
return instance[attr] return instance[attr]
@ -108,6 +110,7 @@ class Field(object):
default_validators = [] default_validators = []
default_empty_html = empty default_empty_html = empty
initial = None initial = None
coerce_blank_to_null = True
def __init__(self, read_only=False, write_only=False, def __init__(self, read_only=False, write_only=False,
required=None, default=empty, initial=empty, source=None, required=None, default=empty, initial=empty, source=None,
@ -245,6 +248,9 @@ class Field(object):
self.fail('required') self.fail('required')
return self.get_default() return self.get_default()
if data == '' and self.coerce_blank_to_null:
data = None
if data is None: if data is None:
if not self.allow_null: if not self.allow_null:
self.fail('null') self.fail('null')
@ -413,6 +419,7 @@ class CharField(Field):
'blank': _('This field may not be blank.') 'blank': _('This field may not be blank.')
} }
initial = '' initial = ''
coerce_blank_to_null = False
def __init__(self, **kwargs): def __init__(self, **kwargs):
self.allow_blank = kwargs.pop('allow_blank', False) self.allow_blank = kwargs.pop('allow_blank', False)

View File

@ -1,461 +1,462 @@
# from __future__ import unicode_literals from __future__ import unicode_literals
# from django.conf.urls import patterns, url from django.conf.urls import patterns, url
# from django.test import TestCase from django.test import TestCase
# from rest_framework import serializers from rest_framework import serializers
# from rest_framework.test import APIRequestFactory from rest_framework.test import APIRequestFactory
# from tests.models import ( from tests.models import (
# BlogPost, ManyToManyTarget, ManyToManySource, ForeignKeyTarget, ForeignKeySource,
# ManyToManyTarget, ManyToManySource, ForeignKeyTarget, ForeignKeySource, NullableForeignKeySource, OneToOneTarget, NullableOneToOneSource
# NullableForeignKeySource, OneToOneTarget, NullableOneToOneSource )
# )
# factory = APIRequestFactory() factory = APIRequestFactory()
# request = factory.get('/') # Just to ensure we have a request in the serializer context request = factory.get('/') # Just to ensure we have a request in the serializer context
# def dummy_view(request, pk): dummy_view = lambda request, pk: None
# pass
# urlpatterns = patterns( urlpatterns = patterns(
# '', '',
# url(r'^dummyurl/(?P<pk>[0-9]+)/$', dummy_view, name='dummy-url'), url(r'^dummyurl/(?P<pk>[0-9]+)/$', dummy_view, name='dummy-url'),
# url(r'^manytomanysource/(?P<pk>[0-9]+)/$', dummy_view, name='manytomanysource-detail'), url(r'^manytomanysource/(?P<pk>[0-9]+)/$', dummy_view, name='manytomanysource-detail'),
# url(r'^manytomanytarget/(?P<pk>[0-9]+)/$', dummy_view, name='manytomanytarget-detail'), url(r'^manytomanytarget/(?P<pk>[0-9]+)/$', dummy_view, name='manytomanytarget-detail'),
# url(r'^foreignkeysource/(?P<pk>[0-9]+)/$', dummy_view, name='foreignkeysource-detail'), url(r'^foreignkeysource/(?P<pk>[0-9]+)/$', dummy_view, name='foreignkeysource-detail'),
# url(r'^foreignkeytarget/(?P<pk>[0-9]+)/$', dummy_view, name='foreignkeytarget-detail'), url(r'^foreignkeytarget/(?P<pk>[0-9]+)/$', dummy_view, name='foreignkeytarget-detail'),
# url(r'^nullableforeignkeysource/(?P<pk>[0-9]+)/$', dummy_view, name='nullableforeignkeysource-detail'), url(r'^nullableforeignkeysource/(?P<pk>[0-9]+)/$', dummy_view, name='nullableforeignkeysource-detail'),
# url(r'^onetoonetarget/(?P<pk>[0-9]+)/$', dummy_view, name='onetoonetarget-detail'), url(r'^onetoonetarget/(?P<pk>[0-9]+)/$', dummy_view, name='onetoonetarget-detail'),
# url(r'^nullableonetoonesource/(?P<pk>[0-9]+)/$', dummy_view, name='nullableonetoonesource-detail'), url(r'^nullableonetoonesource/(?P<pk>[0-9]+)/$', dummy_view, name='nullableonetoonesource-detail'),
# ) )
# # ManyToMany # ManyToMany
# class ManyToManyTargetSerializer(serializers.HyperlinkedModelSerializer): class ManyToManyTargetSerializer(serializers.HyperlinkedModelSerializer):
# class Meta: class Meta:
# model = ManyToManyTarget model = ManyToManyTarget
# fields = ('url', 'name', 'sources') fields = ('url', 'name', 'sources')
# class ManyToManySourceSerializer(serializers.HyperlinkedModelSerializer): class ManyToManySourceSerializer(serializers.HyperlinkedModelSerializer):
# class Meta: class Meta:
# model = ManyToManySource model = ManyToManySource
# fields = ('url', 'name', 'targets') fields = ('url', 'name', 'targets')
# # ForeignKey # ForeignKey
# class ForeignKeyTargetSerializer(serializers.HyperlinkedModelSerializer): class ForeignKeyTargetSerializer(serializers.HyperlinkedModelSerializer):
# class Meta: class Meta:
# model = ForeignKeyTarget model = ForeignKeyTarget
# fields = ('url', 'name', 'sources') fields = ('url', 'name', 'sources')
# class ForeignKeySourceSerializer(serializers.HyperlinkedModelSerializer): class ForeignKeySourceSerializer(serializers.HyperlinkedModelSerializer):
# class Meta: class Meta:
# model = ForeignKeySource model = ForeignKeySource
# fields = ('url', 'name', 'target') fields = ('url', 'name', 'target')
# # Nullable ForeignKey # Nullable ForeignKey
# class NullableForeignKeySourceSerializer(serializers.HyperlinkedModelSerializer): class NullableForeignKeySourceSerializer(serializers.HyperlinkedModelSerializer):
# class Meta: class Meta:
# model = NullableForeignKeySource model = NullableForeignKeySource
# fields = ('url', 'name', 'target') fields = ('url', 'name', 'target')
# # Nullable OneToOne # Nullable OneToOne
# class NullableOneToOneTargetSerializer(serializers.HyperlinkedModelSerializer): class NullableOneToOneTargetSerializer(serializers.HyperlinkedModelSerializer):
# class Meta: class Meta:
# model = OneToOneTarget model = OneToOneTarget
# fields = ('url', 'name', 'nullable_source') fields = ('url', 'name', 'nullable_source')
# # TODO: Add test that .data cannot be accessed prior to .is_valid # TODO: Add test that .data cannot be accessed prior to .is_valid
# class HyperlinkedManyToManyTests(TestCase): class HyperlinkedManyToManyTests(TestCase):
# urls = 'tests.test_relations_hyperlink' urls = 'tests.test_relations_hyperlink'
# def setUp(self): def setUp(self):
# for idx in range(1, 4): for idx in range(1, 4):
# target = ManyToManyTarget(name='target-%d' % idx) target = ManyToManyTarget(name='target-%d' % idx)
# target.save() target.save()
# source = ManyToManySource(name='source-%d' % idx) source = ManyToManySource(name='source-%d' % idx)
# source.save() source.save()
# for target in ManyToManyTarget.objects.all(): for target in ManyToManyTarget.objects.all():
# source.targets.add(target) source.targets.add(target)
# def test_many_to_many_retrieve(self): def test_many_to_many_retrieve(self):
# queryset = ManyToManySource.objects.all() queryset = ManyToManySource.objects.all()
# serializer = ManyToManySourceSerializer(queryset, many=True, context={'request': request}) serializer = ManyToManySourceSerializer(queryset, many=True, context={'request': request})
# expected = [ expected = [
# {'url': 'http://testserver/manytomanysource/1/', 'name': 'source-1', 'targets': ['http://testserver/manytomanytarget/1/']}, {'url': 'http://testserver/manytomanysource/1/', 'name': 'source-1', 'targets': ['http://testserver/manytomanytarget/1/']},
# {'url': 'http://testserver/manytomanysource/2/', 'name': 'source-2', 'targets': ['http://testserver/manytomanytarget/1/', 'http://testserver/manytomanytarget/2/']}, {'url': 'http://testserver/manytomanysource/2/', 'name': 'source-2', 'targets': ['http://testserver/manytomanytarget/1/', 'http://testserver/manytomanytarget/2/']},
# {'url': 'http://testserver/manytomanysource/3/', 'name': 'source-3', 'targets': ['http://testserver/manytomanytarget/1/', 'http://testserver/manytomanytarget/2/', 'http://testserver/manytomanytarget/3/']} {'url': 'http://testserver/manytomanysource/3/', 'name': 'source-3', 'targets': ['http://testserver/manytomanytarget/1/', 'http://testserver/manytomanytarget/2/', 'http://testserver/manytomanytarget/3/']}
# ] ]
# self.assertEqual(serializer.data, expected) self.assertEqual(serializer.data, expected)
# def test_reverse_many_to_many_retrieve(self): def test_reverse_many_to_many_retrieve(self):
# queryset = ManyToManyTarget.objects.all() queryset = ManyToManyTarget.objects.all()
# serializer = ManyToManyTargetSerializer(queryset, many=True, context={'request': request}) serializer = ManyToManyTargetSerializer(queryset, many=True, context={'request': request})
# expected = [ expected = [
# {'url': 'http://testserver/manytomanytarget/1/', 'name': 'target-1', 'sources': ['http://testserver/manytomanysource/1/', 'http://testserver/manytomanysource/2/', 'http://testserver/manytomanysource/3/']}, {'url': 'http://testserver/manytomanytarget/1/', 'name': 'target-1', 'sources': ['http://testserver/manytomanysource/1/', 'http://testserver/manytomanysource/2/', 'http://testserver/manytomanysource/3/']},
# {'url': 'http://testserver/manytomanytarget/2/', 'name': 'target-2', 'sources': ['http://testserver/manytomanysource/2/', 'http://testserver/manytomanysource/3/']}, {'url': 'http://testserver/manytomanytarget/2/', 'name': 'target-2', 'sources': ['http://testserver/manytomanysource/2/', 'http://testserver/manytomanysource/3/']},
# {'url': 'http://testserver/manytomanytarget/3/', 'name': 'target-3', 'sources': ['http://testserver/manytomanysource/3/']} {'url': 'http://testserver/manytomanytarget/3/', 'name': 'target-3', 'sources': ['http://testserver/manytomanysource/3/']}
# ] ]
# self.assertEqual(serializer.data, expected) self.assertEqual(serializer.data, expected)
# def test_many_to_many_update(self): def test_many_to_many_update(self):
# data = {'url': 'http://testserver/manytomanysource/1/', 'name': 'source-1', 'targets': ['http://testserver/manytomanytarget/1/', 'http://testserver/manytomanytarget/2/', 'http://testserver/manytomanytarget/3/']} data = {'url': 'http://testserver/manytomanysource/1/', 'name': 'source-1', 'targets': ['http://testserver/manytomanytarget/1/', 'http://testserver/manytomanytarget/2/', 'http://testserver/manytomanytarget/3/']}
# instance = ManyToManySource.objects.get(pk=1) instance = ManyToManySource.objects.get(pk=1)
# serializer = ManyToManySourceSerializer(instance, data=data, context={'request': request}) serializer = ManyToManySourceSerializer(instance, data=data, context={'request': request})
# self.assertTrue(serializer.is_valid()) self.assertTrue(serializer.is_valid())
# serializer.save() serializer.save()
# self.assertEqual(serializer.data, data) self.assertEqual(serializer.data, data)
# # Ensure source 1 is updated, and everything else is as expected # Ensure source 1 is updated, and everything else is as expected
# queryset = ManyToManySource.objects.all() queryset = ManyToManySource.objects.all()
# serializer = ManyToManySourceSerializer(queryset, many=True, context={'request': request}) serializer = ManyToManySourceSerializer(queryset, many=True, context={'request': request})
# expected = [ expected = [
# {'url': 'http://testserver/manytomanysource/1/', 'name': 'source-1', 'targets': ['http://testserver/manytomanytarget/1/', 'http://testserver/manytomanytarget/2/', 'http://testserver/manytomanytarget/3/']}, {'url': 'http://testserver/manytomanysource/1/', 'name': 'source-1', 'targets': ['http://testserver/manytomanytarget/1/', 'http://testserver/manytomanytarget/2/', 'http://testserver/manytomanytarget/3/']},
# {'url': 'http://testserver/manytomanysource/2/', 'name': 'source-2', 'targets': ['http://testserver/manytomanytarget/1/', 'http://testserver/manytomanytarget/2/']}, {'url': 'http://testserver/manytomanysource/2/', 'name': 'source-2', 'targets': ['http://testserver/manytomanytarget/1/', 'http://testserver/manytomanytarget/2/']},
# {'url': 'http://testserver/manytomanysource/3/', 'name': 'source-3', 'targets': ['http://testserver/manytomanytarget/1/', 'http://testserver/manytomanytarget/2/', 'http://testserver/manytomanytarget/3/']} {'url': 'http://testserver/manytomanysource/3/', 'name': 'source-3', 'targets': ['http://testserver/manytomanytarget/1/', 'http://testserver/manytomanytarget/2/', 'http://testserver/manytomanytarget/3/']}
# ] ]
# self.assertEqual(serializer.data, expected) self.assertEqual(serializer.data, expected)
# def test_reverse_many_to_many_update(self): def test_reverse_many_to_many_update(self):
# data = {'url': 'http://testserver/manytomanytarget/1/', 'name': 'target-1', 'sources': ['http://testserver/manytomanysource/1/']} data = {'url': 'http://testserver/manytomanytarget/1/', 'name': 'target-1', 'sources': ['http://testserver/manytomanysource/1/']}
# instance = ManyToManyTarget.objects.get(pk=1) instance = ManyToManyTarget.objects.get(pk=1)
# serializer = ManyToManyTargetSerializer(instance, data=data, context={'request': request}) serializer = ManyToManyTargetSerializer(instance, data=data, context={'request': request})
# self.assertTrue(serializer.is_valid()) self.assertTrue(serializer.is_valid())
# serializer.save() serializer.save()
# self.assertEqual(serializer.data, data) self.assertEqual(serializer.data, data)
# # Ensure target 1 is updated, and everything else is as expected # Ensure target 1 is updated, and everything else is as expected
# queryset = ManyToManyTarget.objects.all() queryset = ManyToManyTarget.objects.all()
# serializer = ManyToManyTargetSerializer(queryset, many=True, context={'request': request}) serializer = ManyToManyTargetSerializer(queryset, many=True, context={'request': request})
# expected = [ expected = [
# {'url': 'http://testserver/manytomanytarget/1/', 'name': 'target-1', 'sources': ['http://testserver/manytomanysource/1/']}, {'url': 'http://testserver/manytomanytarget/1/', 'name': 'target-1', 'sources': ['http://testserver/manytomanysource/1/']},
# {'url': 'http://testserver/manytomanytarget/2/', 'name': 'target-2', 'sources': ['http://testserver/manytomanysource/2/', 'http://testserver/manytomanysource/3/']}, {'url': 'http://testserver/manytomanytarget/2/', 'name': 'target-2', 'sources': ['http://testserver/manytomanysource/2/', 'http://testserver/manytomanysource/3/']},
# {'url': 'http://testserver/manytomanytarget/3/', 'name': 'target-3', 'sources': ['http://testserver/manytomanysource/3/']} {'url': 'http://testserver/manytomanytarget/3/', 'name': 'target-3', 'sources': ['http://testserver/manytomanysource/3/']}
# ] ]
# self.assertEqual(serializer.data, expected) self.assertEqual(serializer.data, expected)
# def test_many_to_many_create(self): def test_many_to_many_create(self):
# data = {'url': 'http://testserver/manytomanysource/4/', 'name': 'source-4', 'targets': ['http://testserver/manytomanytarget/1/', 'http://testserver/manytomanytarget/3/']} data = {'url': 'http://testserver/manytomanysource/4/', 'name': 'source-4', 'targets': ['http://testserver/manytomanytarget/1/', 'http://testserver/manytomanytarget/3/']}
# serializer = ManyToManySourceSerializer(data=data, context={'request': request}) serializer = ManyToManySourceSerializer(data=data, context={'request': request})
# self.assertTrue(serializer.is_valid()) self.assertTrue(serializer.is_valid())
# obj = serializer.save() obj = serializer.save()
# self.assertEqual(serializer.data, data) self.assertEqual(serializer.data, data)
# self.assertEqual(obj.name, 'source-4') self.assertEqual(obj.name, 'source-4')
# # Ensure source 4 is added, and everything else is as expected # Ensure source 4 is added, and everything else is as expected
# queryset = ManyToManySource.objects.all() queryset = ManyToManySource.objects.all()
# serializer = ManyToManySourceSerializer(queryset, many=True, context={'request': request}) serializer = ManyToManySourceSerializer(queryset, many=True, context={'request': request})
# expected = [ expected = [
# {'url': 'http://testserver/manytomanysource/1/', 'name': 'source-1', 'targets': ['http://testserver/manytomanytarget/1/']}, {'url': 'http://testserver/manytomanysource/1/', 'name': 'source-1', 'targets': ['http://testserver/manytomanytarget/1/']},
# {'url': 'http://testserver/manytomanysource/2/', 'name': 'source-2', 'targets': ['http://testserver/manytomanytarget/1/', 'http://testserver/manytomanytarget/2/']}, {'url': 'http://testserver/manytomanysource/2/', 'name': 'source-2', 'targets': ['http://testserver/manytomanytarget/1/', 'http://testserver/manytomanytarget/2/']},
# {'url': 'http://testserver/manytomanysource/3/', 'name': 'source-3', 'targets': ['http://testserver/manytomanytarget/1/', 'http://testserver/manytomanytarget/2/', 'http://testserver/manytomanytarget/3/']}, {'url': 'http://testserver/manytomanysource/3/', 'name': 'source-3', 'targets': ['http://testserver/manytomanytarget/1/', 'http://testserver/manytomanytarget/2/', 'http://testserver/manytomanytarget/3/']},
# {'url': 'http://testserver/manytomanysource/4/', 'name': 'source-4', 'targets': ['http://testserver/manytomanytarget/1/', 'http://testserver/manytomanytarget/3/']} {'url': 'http://testserver/manytomanysource/4/', 'name': 'source-4', 'targets': ['http://testserver/manytomanytarget/1/', 'http://testserver/manytomanytarget/3/']}
# ] ]
# self.assertEqual(serializer.data, expected) self.assertEqual(serializer.data, expected)
# def test_reverse_many_to_many_create(self): def test_reverse_many_to_many_create(self):
# data = {'url': 'http://testserver/manytomanytarget/4/', 'name': 'target-4', 'sources': ['http://testserver/manytomanysource/1/', 'http://testserver/manytomanysource/3/']} data = {'url': 'http://testserver/manytomanytarget/4/', 'name': 'target-4', 'sources': ['http://testserver/manytomanysource/1/', 'http://testserver/manytomanysource/3/']}
# serializer = ManyToManyTargetSerializer(data=data, context={'request': request}) serializer = ManyToManyTargetSerializer(data=data, context={'request': request})
# self.assertTrue(serializer.is_valid()) self.assertTrue(serializer.is_valid())
# obj = serializer.save() obj = serializer.save()
# self.assertEqual(serializer.data, data) self.assertEqual(serializer.data, data)
# self.assertEqual(obj.name, 'target-4') self.assertEqual(obj.name, 'target-4')
# # Ensure target 4 is added, and everything else is as expected # Ensure target 4 is added, and everything else is as expected
# queryset = ManyToManyTarget.objects.all() queryset = ManyToManyTarget.objects.all()
# serializer = ManyToManyTargetSerializer(queryset, many=True, context={'request': request}) serializer = ManyToManyTargetSerializer(queryset, many=True, context={'request': request})
# expected = [ expected = [
# {'url': 'http://testserver/manytomanytarget/1/', 'name': 'target-1', 'sources': ['http://testserver/manytomanysource/1/', 'http://testserver/manytomanysource/2/', 'http://testserver/manytomanysource/3/']}, {'url': 'http://testserver/manytomanytarget/1/', 'name': 'target-1', 'sources': ['http://testserver/manytomanysource/1/', 'http://testserver/manytomanysource/2/', 'http://testserver/manytomanysource/3/']},
# {'url': 'http://testserver/manytomanytarget/2/', 'name': 'target-2', 'sources': ['http://testserver/manytomanysource/2/', 'http://testserver/manytomanysource/3/']}, {'url': 'http://testserver/manytomanytarget/2/', 'name': 'target-2', 'sources': ['http://testserver/manytomanysource/2/', 'http://testserver/manytomanysource/3/']},
# {'url': 'http://testserver/manytomanytarget/3/', 'name': 'target-3', 'sources': ['http://testserver/manytomanysource/3/']}, {'url': 'http://testserver/manytomanytarget/3/', 'name': 'target-3', 'sources': ['http://testserver/manytomanysource/3/']},
# {'url': 'http://testserver/manytomanytarget/4/', 'name': 'target-4', 'sources': ['http://testserver/manytomanysource/1/', 'http://testserver/manytomanysource/3/']} {'url': 'http://testserver/manytomanytarget/4/', 'name': 'target-4', 'sources': ['http://testserver/manytomanysource/1/', 'http://testserver/manytomanysource/3/']}
# ] ]
# self.assertEqual(serializer.data, expected) self.assertEqual(serializer.data, expected)
# class HyperlinkedForeignKeyTests(TestCase): class HyperlinkedForeignKeyTests(TestCase):
# urls = 'tests.test_relations_hyperlink' urls = 'tests.test_relations_hyperlink'
# def setUp(self): def setUp(self):
# target = ForeignKeyTarget(name='target-1') target = ForeignKeyTarget(name='target-1')
# target.save() target.save()
# new_target = ForeignKeyTarget(name='target-2') new_target = ForeignKeyTarget(name='target-2')
# new_target.save() new_target.save()
# for idx in range(1, 4): for idx in range(1, 4):
# source = ForeignKeySource(name='source-%d' % idx, target=target) source = ForeignKeySource(name='source-%d' % idx, target=target)
# source.save() source.save()
# def test_foreign_key_retrieve(self): def test_foreign_key_retrieve(self):
# queryset = ForeignKeySource.objects.all() queryset = ForeignKeySource.objects.all()
# serializer = ForeignKeySourceSerializer(queryset, many=True, context={'request': request}) serializer = ForeignKeySourceSerializer(queryset, many=True, context={'request': request})
# expected = [ expected = [
# {'url': 'http://testserver/foreignkeysource/1/', 'name': 'source-1', 'target': 'http://testserver/foreignkeytarget/1/'}, {'url': 'http://testserver/foreignkeysource/1/', 'name': 'source-1', 'target': 'http://testserver/foreignkeytarget/1/'},
# {'url': 'http://testserver/foreignkeysource/2/', 'name': 'source-2', 'target': 'http://testserver/foreignkeytarget/1/'}, {'url': 'http://testserver/foreignkeysource/2/', 'name': 'source-2', 'target': 'http://testserver/foreignkeytarget/1/'},
# {'url': 'http://testserver/foreignkeysource/3/', 'name': 'source-3', 'target': 'http://testserver/foreignkeytarget/1/'} {'url': 'http://testserver/foreignkeysource/3/', 'name': 'source-3', 'target': 'http://testserver/foreignkeytarget/1/'}
# ] ]
# self.assertEqual(serializer.data, expected) self.assertEqual(serializer.data, expected)
# def test_reverse_foreign_key_retrieve(self): def test_reverse_foreign_key_retrieve(self):
# queryset = ForeignKeyTarget.objects.all() queryset = ForeignKeyTarget.objects.all()
# serializer = ForeignKeyTargetSerializer(queryset, many=True, context={'request': request}) serializer = ForeignKeyTargetSerializer(queryset, many=True, context={'request': request})
# expected = [ expected = [
# {'url': 'http://testserver/foreignkeytarget/1/', 'name': 'target-1', 'sources': ['http://testserver/foreignkeysource/1/', 'http://testserver/foreignkeysource/2/', 'http://testserver/foreignkeysource/3/']}, {'url': 'http://testserver/foreignkeytarget/1/', 'name': 'target-1', 'sources': ['http://testserver/foreignkeysource/1/', 'http://testserver/foreignkeysource/2/', 'http://testserver/foreignkeysource/3/']},
# {'url': 'http://testserver/foreignkeytarget/2/', 'name': 'target-2', 'sources': []}, {'url': 'http://testserver/foreignkeytarget/2/', 'name': 'target-2', 'sources': []},
# ] ]
# self.assertEqual(serializer.data, expected) self.assertEqual(serializer.data, expected)
# def test_foreign_key_update(self): def test_foreign_key_update(self):
# data = {'url': 'http://testserver/foreignkeysource/1/', 'name': 'source-1', 'target': 'http://testserver/foreignkeytarget/2/'} data = {'url': 'http://testserver/foreignkeysource/1/', 'name': 'source-1', 'target': 'http://testserver/foreignkeytarget/2/'}
# instance = ForeignKeySource.objects.get(pk=1) instance = ForeignKeySource.objects.get(pk=1)
# serializer = ForeignKeySourceSerializer(instance, data=data, context={'request': request}) serializer = ForeignKeySourceSerializer(instance, data=data, context={'request': request})
# self.assertTrue(serializer.is_valid()) self.assertTrue(serializer.is_valid())
# self.assertEqual(serializer.data, data) serializer.save()
# serializer.save() self.assertEqual(serializer.data, data)
# # Ensure source 1 is updated, and everything else is as expected # Ensure source 1 is updated, and everything else is as expected
# queryset = ForeignKeySource.objects.all() queryset = ForeignKeySource.objects.all()
# serializer = ForeignKeySourceSerializer(queryset, many=True, context={'request': request}) serializer = ForeignKeySourceSerializer(queryset, many=True, context={'request': request})
# expected = [ expected = [
# {'url': 'http://testserver/foreignkeysource/1/', 'name': 'source-1', 'target': 'http://testserver/foreignkeytarget/2/'}, {'url': 'http://testserver/foreignkeysource/1/', 'name': 'source-1', 'target': 'http://testserver/foreignkeytarget/2/'},
# {'url': 'http://testserver/foreignkeysource/2/', 'name': 'source-2', 'target': 'http://testserver/foreignkeytarget/1/'}, {'url': 'http://testserver/foreignkeysource/2/', 'name': 'source-2', 'target': 'http://testserver/foreignkeytarget/1/'},
# {'url': 'http://testserver/foreignkeysource/3/', 'name': 'source-3', 'target': 'http://testserver/foreignkeytarget/1/'} {'url': 'http://testserver/foreignkeysource/3/', 'name': 'source-3', 'target': 'http://testserver/foreignkeytarget/1/'}
# ] ]
# self.assertEqual(serializer.data, expected) self.assertEqual(serializer.data, expected)
# def test_foreign_key_update_incorrect_type(self): def test_foreign_key_update_incorrect_type(self):
# data = {'url': 'http://testserver/foreignkeysource/1/', 'name': 'source-1', 'target': 2} data = {'url': 'http://testserver/foreignkeysource/1/', 'name': 'source-1', 'target': 2}
# instance = ForeignKeySource.objects.get(pk=1) instance = ForeignKeySource.objects.get(pk=1)
# serializer = ForeignKeySourceSerializer(instance, data=data, context={'request': request}) serializer = ForeignKeySourceSerializer(instance, data=data, context={'request': request})
# self.assertFalse(serializer.is_valid()) self.assertFalse(serializer.is_valid())
# self.assertEqual(serializer.errors, {'target': ['Incorrect type. Expected url string, received int.']}) self.assertEqual(serializer.errors, {'target': ['Incorrect type. Expected URL string, received int.']})
# def test_reverse_foreign_key_update(self): def test_reverse_foreign_key_update(self):
# data = {'url': 'http://testserver/foreignkeytarget/2/', 'name': 'target-2', 'sources': ['http://testserver/foreignkeysource/1/', 'http://testserver/foreignkeysource/3/']} data = {'url': 'http://testserver/foreignkeytarget/2/', 'name': 'target-2', 'sources': ['http://testserver/foreignkeysource/1/', 'http://testserver/foreignkeysource/3/']}
# instance = ForeignKeyTarget.objects.get(pk=2) instance = ForeignKeyTarget.objects.get(pk=2)
# serializer = ForeignKeyTargetSerializer(instance, data=data, context={'request': request}) serializer = ForeignKeyTargetSerializer(instance, data=data, context={'request': request})
# self.assertTrue(serializer.is_valid()) self.assertTrue(serializer.is_valid())
# # We shouldn't have saved anything to the db yet since save # We shouldn't have saved anything to the db yet since save
# # hasn't been called. # hasn't been called.
# queryset = ForeignKeyTarget.objects.all() queryset = ForeignKeyTarget.objects.all()
# new_serializer = ForeignKeyTargetSerializer(queryset, many=True, context={'request': request}) new_serializer = ForeignKeyTargetSerializer(queryset, many=True, context={'request': request})
# expected = [ expected = [
# {'url': 'http://testserver/foreignkeytarget/1/', 'name': 'target-1', 'sources': ['http://testserver/foreignkeysource/1/', 'http://testserver/foreignkeysource/2/', 'http://testserver/foreignkeysource/3/']}, {'url': 'http://testserver/foreignkeytarget/1/', 'name': 'target-1', 'sources': ['http://testserver/foreignkeysource/1/', 'http://testserver/foreignkeysource/2/', 'http://testserver/foreignkeysource/3/']},
# {'url': 'http://testserver/foreignkeytarget/2/', 'name': 'target-2', 'sources': []}, {'url': 'http://testserver/foreignkeytarget/2/', 'name': 'target-2', 'sources': []},
# ] ]
# self.assertEqual(new_serializer.data, expected) self.assertEqual(new_serializer.data, expected)
# serializer.save() serializer.save()
# self.assertEqual(serializer.data, data) self.assertEqual(serializer.data, data)
# # Ensure target 2 is update, and everything else is as expected # Ensure target 2 is update, and everything else is as expected
# queryset = ForeignKeyTarget.objects.all() queryset = ForeignKeyTarget.objects.all()
# serializer = ForeignKeyTargetSerializer(queryset, many=True, context={'request': request}) serializer = ForeignKeyTargetSerializer(queryset, many=True, context={'request': request})
# expected = [ expected = [
# {'url': 'http://testserver/foreignkeytarget/1/', 'name': 'target-1', 'sources': ['http://testserver/foreignkeysource/2/']}, {'url': 'http://testserver/foreignkeytarget/1/', 'name': 'target-1', 'sources': ['http://testserver/foreignkeysource/2/']},
# {'url': 'http://testserver/foreignkeytarget/2/', 'name': 'target-2', 'sources': ['http://testserver/foreignkeysource/1/', 'http://testserver/foreignkeysource/3/']}, {'url': 'http://testserver/foreignkeytarget/2/', 'name': 'target-2', 'sources': ['http://testserver/foreignkeysource/1/', 'http://testserver/foreignkeysource/3/']},
# ] ]
# self.assertEqual(serializer.data, expected) self.assertEqual(serializer.data, expected)
# def test_foreign_key_create(self): def test_foreign_key_create(self):
# data = {'url': 'http://testserver/foreignkeysource/4/', 'name': 'source-4', 'target': 'http://testserver/foreignkeytarget/2/'} data = {'url': 'http://testserver/foreignkeysource/4/', 'name': 'source-4', 'target': 'http://testserver/foreignkeytarget/2/'}
# serializer = ForeignKeySourceSerializer(data=data, context={'request': request}) serializer = ForeignKeySourceSerializer(data=data, context={'request': request})
# self.assertTrue(serializer.is_valid()) self.assertTrue(serializer.is_valid())
# obj = serializer.save() obj = serializer.save()
# self.assertEqual(serializer.data, data) self.assertEqual(serializer.data, data)
# self.assertEqual(obj.name, 'source-4') self.assertEqual(obj.name, 'source-4')
# # Ensure source 1 is updated, and everything else is as expected # Ensure source 1 is updated, and everything else is as expected
# queryset = ForeignKeySource.objects.all() queryset = ForeignKeySource.objects.all()
# serializer = ForeignKeySourceSerializer(queryset, many=True, context={'request': request}) serializer = ForeignKeySourceSerializer(queryset, many=True, context={'request': request})
# expected = [ expected = [
# {'url': 'http://testserver/foreignkeysource/1/', 'name': 'source-1', 'target': 'http://testserver/foreignkeytarget/1/'}, {'url': 'http://testserver/foreignkeysource/1/', 'name': 'source-1', 'target': 'http://testserver/foreignkeytarget/1/'},
# {'url': 'http://testserver/foreignkeysource/2/', 'name': 'source-2', 'target': 'http://testserver/foreignkeytarget/1/'}, {'url': 'http://testserver/foreignkeysource/2/', 'name': 'source-2', 'target': 'http://testserver/foreignkeytarget/1/'},
# {'url': 'http://testserver/foreignkeysource/3/', 'name': 'source-3', 'target': 'http://testserver/foreignkeytarget/1/'}, {'url': 'http://testserver/foreignkeysource/3/', 'name': 'source-3', 'target': 'http://testserver/foreignkeytarget/1/'},
# {'url': 'http://testserver/foreignkeysource/4/', 'name': 'source-4', 'target': 'http://testserver/foreignkeytarget/2/'}, {'url': 'http://testserver/foreignkeysource/4/', 'name': 'source-4', 'target': 'http://testserver/foreignkeytarget/2/'},
# ] ]
# self.assertEqual(serializer.data, expected) self.assertEqual(serializer.data, expected)
# def test_reverse_foreign_key_create(self): def test_reverse_foreign_key_create(self):
# data = {'url': 'http://testserver/foreignkeytarget/3/', 'name': 'target-3', 'sources': ['http://testserver/foreignkeysource/1/', 'http://testserver/foreignkeysource/3/']} data = {'url': 'http://testserver/foreignkeytarget/3/', 'name': 'target-3', 'sources': ['http://testserver/foreignkeysource/1/', 'http://testserver/foreignkeysource/3/']}
# serializer = ForeignKeyTargetSerializer(data=data, context={'request': request}) serializer = ForeignKeyTargetSerializer(data=data, context={'request': request})
# self.assertTrue(serializer.is_valid()) self.assertTrue(serializer.is_valid())
# obj = serializer.save() obj = serializer.save()
# self.assertEqual(serializer.data, data) self.assertEqual(serializer.data, data)
# self.assertEqual(obj.name, 'target-3') self.assertEqual(obj.name, 'target-3')
# # Ensure target 4 is added, and everything else is as expected # Ensure target 4 is added, and everything else is as expected
# queryset = ForeignKeyTarget.objects.all() queryset = ForeignKeyTarget.objects.all()
# serializer = ForeignKeyTargetSerializer(queryset, many=True, context={'request': request}) serializer = ForeignKeyTargetSerializer(queryset, many=True, context={'request': request})
# expected = [ expected = [
# {'url': 'http://testserver/foreignkeytarget/1/', 'name': 'target-1', 'sources': ['http://testserver/foreignkeysource/2/']}, {'url': 'http://testserver/foreignkeytarget/1/', 'name': 'target-1', 'sources': ['http://testserver/foreignkeysource/2/']},
# {'url': 'http://testserver/foreignkeytarget/2/', 'name': 'target-2', 'sources': []}, {'url': 'http://testserver/foreignkeytarget/2/', 'name': 'target-2', 'sources': []},
# {'url': 'http://testserver/foreignkeytarget/3/', 'name': 'target-3', 'sources': ['http://testserver/foreignkeysource/1/', 'http://testserver/foreignkeysource/3/']}, {'url': 'http://testserver/foreignkeytarget/3/', 'name': 'target-3', 'sources': ['http://testserver/foreignkeysource/1/', 'http://testserver/foreignkeysource/3/']},
# ] ]
# self.assertEqual(serializer.data, expected) self.assertEqual(serializer.data, expected)
# def test_foreign_key_update_with_invalid_null(self): def test_foreign_key_update_with_invalid_null(self):
# data = {'url': 'http://testserver/foreignkeysource/1/', 'name': 'source-1', 'target': None} data = {'url': 'http://testserver/foreignkeysource/1/', 'name': 'source-1', 'target': None}
# instance = ForeignKeySource.objects.get(pk=1) instance = ForeignKeySource.objects.get(pk=1)
# serializer = ForeignKeySourceSerializer(instance, data=data, context={'request': request}) serializer = ForeignKeySourceSerializer(instance, data=data, context={'request': request})
# self.assertFalse(serializer.is_valid()) self.assertFalse(serializer.is_valid())
# self.assertEqual(serializer.errors, {'target': ['This field is required.']}) self.assertEqual(serializer.errors, {'target': ['This field may not be null.']})
# class HyperlinkedNullableForeignKeyTests(TestCase): class HyperlinkedNullableForeignKeyTests(TestCase):
# urls = 'tests.test_relations_hyperlink' urls = 'tests.test_relations_hyperlink'
# def setUp(self): def setUp(self):
# target = ForeignKeyTarget(name='target-1') target = ForeignKeyTarget(name='target-1')
# target.save() target.save()
# for idx in range(1, 4): for idx in range(1, 4):
# if idx == 3: if idx == 3:
# target = None target = None
# source = NullableForeignKeySource(name='source-%d' % idx, target=target) source = NullableForeignKeySource(name='source-%d' % idx, target=target)
# source.save() source.save()
# def test_foreign_key_retrieve_with_null(self): def test_foreign_key_retrieve_with_null(self):
# queryset = NullableForeignKeySource.objects.all() queryset = NullableForeignKeySource.objects.all()
# serializer = NullableForeignKeySourceSerializer(queryset, many=True, context={'request': request}) serializer = NullableForeignKeySourceSerializer(queryset, many=True, context={'request': request})
# expected = [ expected = [
# {'url': 'http://testserver/nullableforeignkeysource/1/', 'name': 'source-1', 'target': 'http://testserver/foreignkeytarget/1/'}, {'url': 'http://testserver/nullableforeignkeysource/1/', 'name': 'source-1', 'target': 'http://testserver/foreignkeytarget/1/'},
# {'url': 'http://testserver/nullableforeignkeysource/2/', 'name': 'source-2', 'target': 'http://testserver/foreignkeytarget/1/'}, {'url': 'http://testserver/nullableforeignkeysource/2/', 'name': 'source-2', 'target': 'http://testserver/foreignkeytarget/1/'},
# {'url': 'http://testserver/nullableforeignkeysource/3/', 'name': 'source-3', 'target': None}, {'url': 'http://testserver/nullableforeignkeysource/3/', 'name': 'source-3', 'target': None},
# ] ]
# self.assertEqual(serializer.data, expected) self.assertEqual(serializer.data, expected)
# def test_foreign_key_create_with_valid_null(self): def test_foreign_key_create_with_valid_null(self):
# data = {'url': 'http://testserver/nullableforeignkeysource/4/', 'name': 'source-4', 'target': None} data = {'url': 'http://testserver/nullableforeignkeysource/4/', 'name': 'source-4', 'target': None}
# serializer = NullableForeignKeySourceSerializer(data=data, context={'request': request}) serializer = NullableForeignKeySourceSerializer(data=data, context={'request': request})
# self.assertTrue(serializer.is_valid()) self.assertTrue(serializer.is_valid())
# obj = serializer.save() obj = serializer.save()
# self.assertEqual(serializer.data, data) self.assertEqual(serializer.data, data)
# self.assertEqual(obj.name, 'source-4') self.assertEqual(obj.name, 'source-4')
# # Ensure source 4 is created, and everything else is as expected # Ensure source 4 is created, and everything else is as expected
# queryset = NullableForeignKeySource.objects.all() queryset = NullableForeignKeySource.objects.all()
# serializer = NullableForeignKeySourceSerializer(queryset, many=True, context={'request': request}) serializer = NullableForeignKeySourceSerializer(queryset, many=True, context={'request': request})
# expected = [ expected = [
# {'url': 'http://testserver/nullableforeignkeysource/1/', 'name': 'source-1', 'target': 'http://testserver/foreignkeytarget/1/'}, {'url': 'http://testserver/nullableforeignkeysource/1/', 'name': 'source-1', 'target': 'http://testserver/foreignkeytarget/1/'},
# {'url': 'http://testserver/nullableforeignkeysource/2/', 'name': 'source-2', 'target': 'http://testserver/foreignkeytarget/1/'}, {'url': 'http://testserver/nullableforeignkeysource/2/', 'name': 'source-2', 'target': 'http://testserver/foreignkeytarget/1/'},
# {'url': 'http://testserver/nullableforeignkeysource/3/', 'name': 'source-3', 'target': None}, {'url': 'http://testserver/nullableforeignkeysource/3/', 'name': 'source-3', 'target': None},
# {'url': 'http://testserver/nullableforeignkeysource/4/', 'name': 'source-4', 'target': None} {'url': 'http://testserver/nullableforeignkeysource/4/', 'name': 'source-4', 'target': None}
# ] ]
# self.assertEqual(serializer.data, expected) self.assertEqual(serializer.data, expected)
# def test_foreign_key_create_with_valid_emptystring(self): def test_foreign_key_create_with_valid_emptystring(self):
# """ """
# The emptystring should be interpreted as null in the context The emptystring should be interpreted as null in the context
# of relationships. of relationships.
# """ """
# data = {'url': 'http://testserver/nullableforeignkeysource/4/', 'name': 'source-4', 'target': ''} data = {'url': 'http://testserver/nullableforeignkeysource/4/', 'name': 'source-4', 'target': ''}
# expected_data = {'url': 'http://testserver/nullableforeignkeysource/4/', 'name': 'source-4', 'target': None} expected_data = {'url': 'http://testserver/nullableforeignkeysource/4/', 'name': 'source-4', 'target': None}
# serializer = NullableForeignKeySourceSerializer(data=data, context={'request': request}) serializer = NullableForeignKeySourceSerializer(data=data, context={'request': request})
# self.assertTrue(serializer.is_valid()) self.assertTrue(serializer.is_valid())
# obj = serializer.save() obj = serializer.save()
# self.assertEqual(serializer.data, expected_data) self.assertEqual(serializer.data, expected_data)
# self.assertEqual(obj.name, 'source-4') self.assertEqual(obj.name, 'source-4')
# # Ensure source 4 is created, and everything else is as expected # Ensure source 4 is created, and everything else is as expected
# queryset = NullableForeignKeySource.objects.all() queryset = NullableForeignKeySource.objects.all()
# serializer = NullableForeignKeySourceSerializer(queryset, many=True, context={'request': request}) serializer = NullableForeignKeySourceSerializer(queryset, many=True, context={'request': request})
# expected = [ expected = [
# {'url': 'http://testserver/nullableforeignkeysource/1/', 'name': 'source-1', 'target': 'http://testserver/foreignkeytarget/1/'}, {'url': 'http://testserver/nullableforeignkeysource/1/', 'name': 'source-1', 'target': 'http://testserver/foreignkeytarget/1/'},
# {'url': 'http://testserver/nullableforeignkeysource/2/', 'name': 'source-2', 'target': 'http://testserver/foreignkeytarget/1/'}, {'url': 'http://testserver/nullableforeignkeysource/2/', 'name': 'source-2', 'target': 'http://testserver/foreignkeytarget/1/'},
# {'url': 'http://testserver/nullableforeignkeysource/3/', 'name': 'source-3', 'target': None}, {'url': 'http://testserver/nullableforeignkeysource/3/', 'name': 'source-3', 'target': None},
# {'url': 'http://testserver/nullableforeignkeysource/4/', 'name': 'source-4', 'target': None} {'url': 'http://testserver/nullableforeignkeysource/4/', 'name': 'source-4', 'target': None}
# ] ]
# self.assertEqual(serializer.data, expected) self.assertEqual(serializer.data, expected)
# def test_foreign_key_update_with_valid_null(self): def test_foreign_key_update_with_valid_null(self):
# data = {'url': 'http://testserver/nullableforeignkeysource/1/', 'name': 'source-1', 'target': None} data = {'url': 'http://testserver/nullableforeignkeysource/1/', 'name': 'source-1', 'target': None}
# instance = NullableForeignKeySource.objects.get(pk=1) instance = NullableForeignKeySource.objects.get(pk=1)
# serializer = NullableForeignKeySourceSerializer(instance, data=data, context={'request': request}) serializer = NullableForeignKeySourceSerializer(instance, data=data, context={'request': request})
# self.assertTrue(serializer.is_valid()) self.assertTrue(serializer.is_valid())
# self.assertEqual(serializer.data, data) serializer.save()
# serializer.save() self.assertEqual(serializer.data, data)
# # Ensure source 1 is updated, and everything else is as expected # Ensure source 1 is updated, and everything else is as expected
# queryset = NullableForeignKeySource.objects.all() queryset = NullableForeignKeySource.objects.all()
# serializer = NullableForeignKeySourceSerializer(queryset, many=True, context={'request': request}) serializer = NullableForeignKeySourceSerializer(queryset, many=True, context={'request': request})
# expected = [ expected = [
# {'url': 'http://testserver/nullableforeignkeysource/1/', 'name': 'source-1', 'target': None}, {'url': 'http://testserver/nullableforeignkeysource/1/', 'name': 'source-1', 'target': None},
# {'url': 'http://testserver/nullableforeignkeysource/2/', 'name': 'source-2', 'target': 'http://testserver/foreignkeytarget/1/'}, {'url': 'http://testserver/nullableforeignkeysource/2/', 'name': 'source-2', 'target': 'http://testserver/foreignkeytarget/1/'},
# {'url': 'http://testserver/nullableforeignkeysource/3/', 'name': 'source-3', 'target': None}, {'url': 'http://testserver/nullableforeignkeysource/3/', 'name': 'source-3', 'target': None},
# ] ]
# self.assertEqual(serializer.data, expected) self.assertEqual(serializer.data, expected)
# def test_foreign_key_update_with_valid_emptystring(self): def test_foreign_key_update_with_valid_emptystring(self):
# """ """
# The emptystring should be interpreted as null in the context The emptystring should be interpreted as null in the context
# of relationships. of relationships.
# """ """
# data = {'url': 'http://testserver/nullableforeignkeysource/1/', 'name': 'source-1', 'target': ''} data = {'url': 'http://testserver/nullableforeignkeysource/1/', 'name': 'source-1', 'target': ''}
# expected_data = {'url': 'http://testserver/nullableforeignkeysource/1/', 'name': 'source-1', 'target': None} expected_data = {'url': 'http://testserver/nullableforeignkeysource/1/', 'name': 'source-1', 'target': None}
# instance = NullableForeignKeySource.objects.get(pk=1) instance = NullableForeignKeySource.objects.get(pk=1)
# serializer = NullableForeignKeySourceSerializer(instance, data=data, context={'request': request}) serializer = NullableForeignKeySourceSerializer(instance, data=data, context={'request': request})
# self.assertTrue(serializer.is_valid()) self.assertTrue(serializer.is_valid())
# self.assertEqual(serializer.data, expected_data) serializer.save()
# serializer.save() self.assertEqual(serializer.data, expected_data)
# # Ensure source 1 is updated, and everything else is as expected # Ensure source 1 is updated, and everything else is as expected
# queryset = NullableForeignKeySource.objects.all() queryset = NullableForeignKeySource.objects.all()
# serializer = NullableForeignKeySourceSerializer(queryset, many=True, context={'request': request}) serializer = NullableForeignKeySourceSerializer(queryset, many=True, context={'request': request})
# expected = [ expected = [
# {'url': 'http://testserver/nullableforeignkeysource/1/', 'name': 'source-1', 'target': None}, {'url': 'http://testserver/nullableforeignkeysource/1/', 'name': 'source-1', 'target': None},
# {'url': 'http://testserver/nullableforeignkeysource/2/', 'name': 'source-2', 'target': 'http://testserver/foreignkeytarget/1/'}, {'url': 'http://testserver/nullableforeignkeysource/2/', 'name': 'source-2', 'target': 'http://testserver/foreignkeytarget/1/'},
# {'url': 'http://testserver/nullableforeignkeysource/3/', 'name': 'source-3', 'target': None}, {'url': 'http://testserver/nullableforeignkeysource/3/', 'name': 'source-3', 'target': None},
# ] ]
# self.assertEqual(serializer.data, expected) self.assertEqual(serializer.data, expected)
# # reverse foreign keys MUST be read_only # # reverse foreign keys MUST be read_only
# # In the general case they do not provide .remove() or .clear() # # In the general case they do not provide .remove() or .clear()
# # and cannot be arbitrarily set. # # and cannot be arbitrarily set.
# # def test_reverse_foreign_key_update(self): # def test_reverse_foreign_key_update(self):
# # data = {'id': 1, 'name': 'target-1', 'sources': [1]} # data = {'id': 1, 'name': 'target-1', 'sources': [1]}
# # instance = ForeignKeyTarget.objects.get(pk=1) # instance = ForeignKeyTarget.objects.get(pk=1)
# # serializer = ForeignKeyTargetSerializer(instance, data=data) # serializer = ForeignKeyTargetSerializer(instance, data=data)
# # self.assertTrue(serializer.is_valid()) # print serializer.is_valid()
# # self.assertEqual(serializer.data, data) # print serializer.errors
# # serializer.save() # print serializer
# self.assertTrue(serializer.is_valid())
# serializer.save()
# self.assertEqual(serializer.data, data)
# # # Ensure target 1 is updated, and everything else is as expected # # Ensure target 1 is updated, and everything else is as expected
# # queryset = ForeignKeyTarget.objects.all() # queryset = ForeignKeyTarget.objects.all()
# # serializer = ForeignKeyTargetSerializer(queryset, many=True) # serializer = ForeignKeyTargetSerializer(queryset, many=True)
# # expected = [
# # {'id': 1, 'name': 'target-1', 'sources': [1]},
# # {'id': 2, 'name': 'target-2', 'sources': []},
# # ]
# # self.assertEqual(serializer.data, expected)
# class HyperlinkedNullableOneToOneTests(TestCase):
# urls = 'tests.test_relations_hyperlink'
# def setUp(self):
# target = OneToOneTarget(name='target-1')
# target.save()
# new_target = OneToOneTarget(name='target-2')
# new_target.save()
# source = NullableOneToOneSource(name='source-1', target=target)
# source.save()
# def test_reverse_foreign_key_retrieve_with_null(self):
# queryset = OneToOneTarget.objects.all()
# serializer = NullableOneToOneTargetSerializer(queryset, many=True, context={'request': request})
# expected = [ # expected = [
# {'url': 'http://testserver/onetoonetarget/1/', 'name': 'target-1', 'nullable_source': 'http://testserver/nullableonetoonesource/1/'}, # {'id': 1, 'name': 'target-1', 'sources': [1]},
# {'url': 'http://testserver/onetoonetarget/2/', 'name': 'target-2', 'nullable_source': None}, # {'id': 2, 'name': 'target-2', 'sources': []},
# ] # ]
# self.assertEqual(serializer.data, expected) # self.assertEqual(serializer.data, expected)
class HyperlinkedNullableOneToOneTests(TestCase):
urls = 'tests.test_relations_hyperlink'
def setUp(self):
target = OneToOneTarget(name='target-1')
target.save()
new_target = OneToOneTarget(name='target-2')
new_target.save()
source = NullableOneToOneSource(name='source-1', target=target)
source.save()
def test_reverse_foreign_key_retrieve_with_null(self):
queryset = OneToOneTarget.objects.all()
serializer = NullableOneToOneTargetSerializer(queryset, many=True, context={'request': request})
expected = [
{'url': 'http://testserver/onetoonetarget/1/', 'name': 'target-1', 'nullable_source': 'http://testserver/nullableonetoonesource/1/'},
{'url': 'http://testserver/onetoonetarget/2/', 'name': 'target-2', 'nullable_source': None},
]
self.assertEqual(serializer.data, expected)
# # Regression tests for #694 (`source` attribute on related fields) # # Regression tests for #694 (`source` attribute on related fields)
# class HyperlinkedRelatedFieldSourceTests(TestCase): # class HyperlinkedRelatedFieldSourceTests(TestCase):

View File

@ -1,446 +1,443 @@
# from __future__ import unicode_literals from __future__ import unicode_literals
# from django.db import models from django.test import TestCase
# from django.test import TestCase from django.utils import six
# from django.utils import six from rest_framework import serializers
# from rest_framework import serializers from tests.models import (
# from tests.models import ( ManyToManyTarget, ManyToManySource, ForeignKeyTarget, ForeignKeySource,
# BlogPost, ManyToManyTarget, ManyToManySource, ForeignKeyTarget, ForeignKeySource, NullableForeignKeySource, OneToOneTarget, NullableOneToOneSource,
# NullableForeignKeySource, OneToOneTarget, NullableOneToOneSource, )
# )
# # ManyToMany # ManyToMany
# class ManyToManyTargetSerializer(serializers.ModelSerializer): class ManyToManyTargetSerializer(serializers.ModelSerializer):
# class Meta: class Meta:
# model = ManyToManyTarget model = ManyToManyTarget
# fields = ('id', 'name', 'sources') fields = ('id', 'name', 'sources')
# class ManyToManySourceSerializer(serializers.ModelSerializer): class ManyToManySourceSerializer(serializers.ModelSerializer):
# class Meta: class Meta:
# model = ManyToManySource model = ManyToManySource
# fields = ('id', 'name', 'targets') fields = ('id', 'name', 'targets')
# # ForeignKey # ForeignKey
# class ForeignKeyTargetSerializer(serializers.ModelSerializer): class ForeignKeyTargetSerializer(serializers.ModelSerializer):
# class Meta: class Meta:
# model = ForeignKeyTarget model = ForeignKeyTarget
# fields = ('id', 'name', 'sources') fields = ('id', 'name', 'sources')
# class ForeignKeySourceSerializer(serializers.ModelSerializer): class ForeignKeySourceSerializer(serializers.ModelSerializer):
# class Meta: class Meta:
# model = ForeignKeySource model = ForeignKeySource
# fields = ('id', 'name', 'target') fields = ('id', 'name', 'target')
# # Nullable ForeignKey # Nullable ForeignKey
# class NullableForeignKeySourceSerializer(serializers.ModelSerializer): class NullableForeignKeySourceSerializer(serializers.ModelSerializer):
# class Meta: class Meta:
# model = NullableForeignKeySource model = NullableForeignKeySource
# fields = ('id', 'name', 'target') fields = ('id', 'name', 'target')
# # Nullable OneToOne # Nullable OneToOne
# class NullableOneToOneTargetSerializer(serializers.ModelSerializer): class NullableOneToOneTargetSerializer(serializers.ModelSerializer):
# class Meta: class Meta:
# model = OneToOneTarget model = OneToOneTarget
# fields = ('id', 'name', 'nullable_source') fields = ('id', 'name', 'nullable_source')
# # TODO: Add test that .data cannot be accessed prior to .is_valid # TODO: Add test that .data cannot be accessed prior to .is_valid
# class PKManyToManyTests(TestCase): class PKManyToManyTests(TestCase):
# def setUp(self): def setUp(self):
# for idx in range(1, 4): for idx in range(1, 4):
# target = ManyToManyTarget(name='target-%d' % idx) target = ManyToManyTarget(name='target-%d' % idx)
# target.save() target.save()
# source = ManyToManySource(name='source-%d' % idx) source = ManyToManySource(name='source-%d' % idx)
# source.save() source.save()
# for target in ManyToManyTarget.objects.all(): for target in ManyToManyTarget.objects.all():
# source.targets.add(target) source.targets.add(target)
# def test_many_to_many_retrieve(self): def test_many_to_many_retrieve(self):
# queryset = ManyToManySource.objects.all() queryset = ManyToManySource.objects.all()
# serializer = ManyToManySourceSerializer(queryset, many=True) serializer = ManyToManySourceSerializer(queryset, many=True)
# expected = [ expected = [
# {'id': 1, 'name': 'source-1', 'targets': [1]}, {'id': 1, 'name': 'source-1', 'targets': [1]},
# {'id': 2, 'name': 'source-2', 'targets': [1, 2]}, {'id': 2, 'name': 'source-2', 'targets': [1, 2]},
# {'id': 3, 'name': 'source-3', 'targets': [1, 2, 3]} {'id': 3, 'name': 'source-3', 'targets': [1, 2, 3]}
# ] ]
# self.assertEqual(serializer.data, expected) self.assertEqual(serializer.data, expected)
# def test_reverse_many_to_many_retrieve(self): def test_reverse_many_to_many_retrieve(self):
# queryset = ManyToManyTarget.objects.all() queryset = ManyToManyTarget.objects.all()
# serializer = ManyToManyTargetSerializer(queryset, many=True) serializer = ManyToManyTargetSerializer(queryset, many=True)
# expected = [ expected = [
# {'id': 1, 'name': 'target-1', 'sources': [1, 2, 3]}, {'id': 1, 'name': 'target-1', 'sources': [1, 2, 3]},
# {'id': 2, 'name': 'target-2', 'sources': [2, 3]}, {'id': 2, 'name': 'target-2', 'sources': [2, 3]},
# {'id': 3, 'name': 'target-3', 'sources': [3]} {'id': 3, 'name': 'target-3', 'sources': [3]}
# ] ]
# self.assertEqual(serializer.data, expected) self.assertEqual(serializer.data, expected)
# def test_many_to_many_update(self): def test_many_to_many_update(self):
# data = {'id': 1, 'name': 'source-1', 'targets': [1, 2, 3]} data = {'id': 1, 'name': 'source-1', 'targets': [1, 2, 3]}
# instance = ManyToManySource.objects.get(pk=1) instance = ManyToManySource.objects.get(pk=1)
# serializer = ManyToManySourceSerializer(instance, data=data) serializer = ManyToManySourceSerializer(instance, data=data)
# self.assertTrue(serializer.is_valid()) self.assertTrue(serializer.is_valid())
# serializer.save() serializer.save()
# self.assertEqual(serializer.data, data) self.assertEqual(serializer.data, data)
# # Ensure source 1 is updated, and everything else is as expected # Ensure source 1 is updated, and everything else is as expected
# queryset = ManyToManySource.objects.all() queryset = ManyToManySource.objects.all()
# serializer = ManyToManySourceSerializer(queryset, many=True) serializer = ManyToManySourceSerializer(queryset, many=True)
# expected = [ expected = [
# {'id': 1, 'name': 'source-1', 'targets': [1, 2, 3]}, {'id': 1, 'name': 'source-1', 'targets': [1, 2, 3]},
# {'id': 2, 'name': 'source-2', 'targets': [1, 2]}, {'id': 2, 'name': 'source-2', 'targets': [1, 2]},
# {'id': 3, 'name': 'source-3', 'targets': [1, 2, 3]} {'id': 3, 'name': 'source-3', 'targets': [1, 2, 3]}
# ] ]
# self.assertEqual(serializer.data, expected) self.assertEqual(serializer.data, expected)
# def test_reverse_many_to_many_update(self): def test_reverse_many_to_many_update(self):
# data = {'id': 1, 'name': 'target-1', 'sources': [1]} data = {'id': 1, 'name': 'target-1', 'sources': [1]}
# instance = ManyToManyTarget.objects.get(pk=1) instance = ManyToManyTarget.objects.get(pk=1)
# serializer = ManyToManyTargetSerializer(instance, data=data) serializer = ManyToManyTargetSerializer(instance, data=data)
# self.assertTrue(serializer.is_valid()) self.assertTrue(serializer.is_valid())
# serializer.save() serializer.save()
# self.assertEqual(serializer.data, data) self.assertEqual(serializer.data, data)
# # Ensure target 1 is updated, and everything else is as expected # Ensure target 1 is updated, and everything else is as expected
# queryset = ManyToManyTarget.objects.all() queryset = ManyToManyTarget.objects.all()
# serializer = ManyToManyTargetSerializer(queryset, many=True) serializer = ManyToManyTargetSerializer(queryset, many=True)
# expected = [ expected = [
# {'id': 1, 'name': 'target-1', 'sources': [1]}, {'id': 1, 'name': 'target-1', 'sources': [1]},
# {'id': 2, 'name': 'target-2', 'sources': [2, 3]}, {'id': 2, 'name': 'target-2', 'sources': [2, 3]},
# {'id': 3, 'name': 'target-3', 'sources': [3]} {'id': 3, 'name': 'target-3', 'sources': [3]}
# ] ]
# self.assertEqual(serializer.data, expected) self.assertEqual(serializer.data, expected)
# def test_many_to_many_create(self): def test_many_to_many_create(self):
# data = {'id': 4, 'name': 'source-4', 'targets': [1, 3]} data = {'id': 4, 'name': 'source-4', 'targets': [1, 3]}
# serializer = ManyToManySourceSerializer(data=data) serializer = ManyToManySourceSerializer(data=data)
# self.assertTrue(serializer.is_valid()) self.assertTrue(serializer.is_valid())
# obj = serializer.save() obj = serializer.save()
# self.assertEqual(serializer.data, data) self.assertEqual(serializer.data, data)
# self.assertEqual(obj.name, 'source-4') self.assertEqual(obj.name, 'source-4')
# # Ensure source 4 is added, and everything else is as expected # Ensure source 4 is added, and everything else is as expected
# queryset = ManyToManySource.objects.all() queryset = ManyToManySource.objects.all()
# serializer = ManyToManySourceSerializer(queryset, many=True) serializer = ManyToManySourceSerializer(queryset, many=True)
# self.assertFalse(serializer.fields['targets'].read_only) expected = [
# expected = [ {'id': 1, 'name': 'source-1', 'targets': [1]},
# {'id': 1, 'name': 'source-1', 'targets': [1]}, {'id': 2, 'name': 'source-2', 'targets': [1, 2]},
# {'id': 2, 'name': 'source-2', 'targets': [1, 2]}, {'id': 3, 'name': 'source-3', 'targets': [1, 2, 3]},
# {'id': 3, 'name': 'source-3', 'targets': [1, 2, 3]}, {'id': 4, 'name': 'source-4', 'targets': [1, 3]},
# {'id': 4, 'name': 'source-4', 'targets': [1, 3]}, ]
# ] self.assertEqual(serializer.data, expected)
# self.assertEqual(serializer.data, expected)
# def test_reverse_many_to_many_create(self): def test_reverse_many_to_many_create(self):
# data = {'id': 4, 'name': 'target-4', 'sources': [1, 3]} data = {'id': 4, 'name': 'target-4', 'sources': [1, 3]}
# serializer = ManyToManyTargetSerializer(data=data) serializer = ManyToManyTargetSerializer(data=data)
# self.assertFalse(serializer.fields['sources'].read_only) self.assertTrue(serializer.is_valid())
# self.assertTrue(serializer.is_valid()) obj = serializer.save()
# obj = serializer.save() self.assertEqual(serializer.data, data)
# self.assertEqual(serializer.data, data) self.assertEqual(obj.name, 'target-4')
# self.assertEqual(obj.name, 'target-4')
# # Ensure target 4 is added, and everything else is as expected # Ensure target 4 is added, and everything else is as expected
# queryset = ManyToManyTarget.objects.all() queryset = ManyToManyTarget.objects.all()
# serializer = ManyToManyTargetSerializer(queryset, many=True) serializer = ManyToManyTargetSerializer(queryset, many=True)
# expected = [ expected = [
# {'id': 1, 'name': 'target-1', 'sources': [1, 2, 3]}, {'id': 1, 'name': 'target-1', 'sources': [1, 2, 3]},
# {'id': 2, 'name': 'target-2', 'sources': [2, 3]}, {'id': 2, 'name': 'target-2', 'sources': [2, 3]},
# {'id': 3, 'name': 'target-3', 'sources': [3]}, {'id': 3, 'name': 'target-3', 'sources': [3]},
# {'id': 4, 'name': 'target-4', 'sources': [1, 3]} {'id': 4, 'name': 'target-4', 'sources': [1, 3]}
# ] ]
# self.assertEqual(serializer.data, expected) self.assertEqual(serializer.data, expected)
# class PKForeignKeyTests(TestCase): class PKForeignKeyTests(TestCase):
# def setUp(self): def setUp(self):
# target = ForeignKeyTarget(name='target-1') target = ForeignKeyTarget(name='target-1')
# target.save() target.save()
# new_target = ForeignKeyTarget(name='target-2') new_target = ForeignKeyTarget(name='target-2')
# new_target.save() new_target.save()
# for idx in range(1, 4): for idx in range(1, 4):
# source = ForeignKeySource(name='source-%d' % idx, target=target) source = ForeignKeySource(name='source-%d' % idx, target=target)
# source.save() source.save()
# def test_foreign_key_retrieve(self): def test_foreign_key_retrieve(self):
# queryset = ForeignKeySource.objects.all() queryset = ForeignKeySource.objects.all()
# serializer = ForeignKeySourceSerializer(queryset, many=True) serializer = ForeignKeySourceSerializer(queryset, many=True)
# expected = [ expected = [
# {'id': 1, 'name': 'source-1', 'target': 1}, {'id': 1, 'name': 'source-1', 'target': 1},
# {'id': 2, 'name': 'source-2', 'target': 1}, {'id': 2, 'name': 'source-2', 'target': 1},
# {'id': 3, 'name': 'source-3', 'target': 1} {'id': 3, 'name': 'source-3', 'target': 1}
# ] ]
# self.assertEqual(serializer.data, expected) self.assertEqual(serializer.data, expected)
# def test_reverse_foreign_key_retrieve(self): def test_reverse_foreign_key_retrieve(self):
# queryset = ForeignKeyTarget.objects.all() queryset = ForeignKeyTarget.objects.all()
# serializer = ForeignKeyTargetSerializer(queryset, many=True) serializer = ForeignKeyTargetSerializer(queryset, many=True)
# expected = [ expected = [
# {'id': 1, 'name': 'target-1', 'sources': [1, 2, 3]}, {'id': 1, 'name': 'target-1', 'sources': [1, 2, 3]},
# {'id': 2, 'name': 'target-2', 'sources': []}, {'id': 2, 'name': 'target-2', 'sources': []},
# ] ]
# self.assertEqual(serializer.data, expected) self.assertEqual(serializer.data, expected)
# def test_foreign_key_update(self): def test_foreign_key_update(self):
# data = {'id': 1, 'name': 'source-1', 'target': 2} data = {'id': 1, 'name': 'source-1', 'target': 2}
# instance = ForeignKeySource.objects.get(pk=1) instance = ForeignKeySource.objects.get(pk=1)
# serializer = ForeignKeySourceSerializer(instance, data=data) serializer = ForeignKeySourceSerializer(instance, data=data)
# self.assertTrue(serializer.is_valid()) self.assertTrue(serializer.is_valid())
# self.assertEqual(serializer.data, data) serializer.save()
# serializer.save() self.assertEqual(serializer.data, data)
# # Ensure source 1 is updated, and everything else is as expected # Ensure source 1 is updated, and everything else is as expected
# queryset = ForeignKeySource.objects.all() queryset = ForeignKeySource.objects.all()
# serializer = ForeignKeySourceSerializer(queryset, many=True) serializer = ForeignKeySourceSerializer(queryset, many=True)
# expected = [ expected = [
# {'id': 1, 'name': 'source-1', 'target': 2}, {'id': 1, 'name': 'source-1', 'target': 2},
# {'id': 2, 'name': 'source-2', 'target': 1}, {'id': 2, 'name': 'source-2', 'target': 1},
# {'id': 3, 'name': 'source-3', 'target': 1} {'id': 3, 'name': 'source-3', 'target': 1}
# ] ]
# self.assertEqual(serializer.data, expected) self.assertEqual(serializer.data, expected)
# def test_foreign_key_update_incorrect_type(self): def test_foreign_key_update_incorrect_type(self):
# data = {'id': 1, 'name': 'source-1', 'target': 'foo'} data = {'id': 1, 'name': 'source-1', 'target': 'foo'}
# instance = ForeignKeySource.objects.get(pk=1) instance = ForeignKeySource.objects.get(pk=1)
# serializer = ForeignKeySourceSerializer(instance, data=data) serializer = ForeignKeySourceSerializer(instance, data=data)
# self.assertFalse(serializer.is_valid()) self.assertFalse(serializer.is_valid())
# self.assertEqual(serializer.errors, {'target': ['Incorrect type. Expected pk value, received %s.' % six.text_type.__name__]}) self.assertEqual(serializer.errors, {'target': ['Incorrect type. Expected pk value, received %s.' % six.text_type.__name__]})
def test_reverse_foreign_key_update(self):
data = {'id': 2, 'name': 'target-2', 'sources': [1, 3]}
instance = ForeignKeyTarget.objects.get(pk=2)
serializer = ForeignKeyTargetSerializer(instance, data=data)
self.assertTrue(serializer.is_valid())
# We shouldn't have saved anything to the db yet since save
# hasn't been called.
queryset = ForeignKeyTarget.objects.all()
new_serializer = ForeignKeyTargetSerializer(queryset, many=True)
expected = [
{'id': 1, 'name': 'target-1', 'sources': [1, 2, 3]},
{'id': 2, 'name': 'target-2', 'sources': []},
]
self.assertEqual(new_serializer.data, expected)
serializer.save()
self.assertEqual(serializer.data, data)
# Ensure target 2 is update, and everything else is as expected
queryset = ForeignKeyTarget.objects.all()
serializer = ForeignKeyTargetSerializer(queryset, many=True)
expected = [
{'id': 1, 'name': 'target-1', 'sources': [2]},
{'id': 2, 'name': 'target-2', 'sources': [1, 3]},
]
self.assertEqual(serializer.data, expected)
def test_foreign_key_create(self):
data = {'id': 4, 'name': 'source-4', 'target': 2}
serializer = ForeignKeySourceSerializer(data=data)
self.assertTrue(serializer.is_valid())
obj = serializer.save()
self.assertEqual(serializer.data, data)
self.assertEqual(obj.name, 'source-4')
# Ensure source 4 is added, and everything else is as expected
queryset = ForeignKeySource.objects.all()
serializer = ForeignKeySourceSerializer(queryset, many=True)
expected = [
{'id': 1, 'name': 'source-1', 'target': 1},
{'id': 2, 'name': 'source-2', 'target': 1},
{'id': 3, 'name': 'source-3', 'target': 1},
{'id': 4, 'name': 'source-4', 'target': 2},
]
self.assertEqual(serializer.data, expected)
def test_reverse_foreign_key_create(self):
data = {'id': 3, 'name': 'target-3', 'sources': [1, 3]}
serializer = ForeignKeyTargetSerializer(data=data)
self.assertTrue(serializer.is_valid())
obj = serializer.save()
self.assertEqual(serializer.data, data)
self.assertEqual(obj.name, 'target-3')
# Ensure target 3 is added, and everything else is as expected
queryset = ForeignKeyTarget.objects.all()
serializer = ForeignKeyTargetSerializer(queryset, many=True)
expected = [
{'id': 1, 'name': 'target-1', 'sources': [2]},
{'id': 2, 'name': 'target-2', 'sources': []},
{'id': 3, 'name': 'target-3', 'sources': [1, 3]},
]
self.assertEqual(serializer.data, expected)
def test_foreign_key_update_with_invalid_null(self):
data = {'id': 1, 'name': 'source-1', 'target': None}
instance = ForeignKeySource.objects.get(pk=1)
serializer = ForeignKeySourceSerializer(instance, data=data)
self.assertFalse(serializer.is_valid())
self.assertEqual(serializer.errors, {'target': ['This field may not be null.']})
def test_foreign_key_with_empty(self):
"""
Regression test for #1072
https://github.com/tomchristie/django-rest-framework/issues/1072
"""
serializer = NullableForeignKeySourceSerializer()
self.assertEqual(serializer.data['target'], None)
class PKNullableForeignKeyTests(TestCase):
def setUp(self):
target = ForeignKeyTarget(name='target-1')
target.save()
for idx in range(1, 4):
if idx == 3:
target = None
source = NullableForeignKeySource(name='source-%d' % idx, target=target)
source.save()
def test_foreign_key_retrieve_with_null(self):
queryset = NullableForeignKeySource.objects.all()
serializer = NullableForeignKeySourceSerializer(queryset, many=True)
expected = [
{'id': 1, 'name': 'source-1', 'target': 1},
{'id': 2, 'name': 'source-2', 'target': 1},
{'id': 3, 'name': 'source-3', 'target': None},
]
self.assertEqual(serializer.data, expected)
def test_foreign_key_create_with_valid_null(self):
data = {'id': 4, 'name': 'source-4', 'target': None}
serializer = NullableForeignKeySourceSerializer(data=data)
self.assertTrue(serializer.is_valid())
obj = serializer.save()
self.assertEqual(serializer.data, data)
self.assertEqual(obj.name, 'source-4')
# Ensure source 4 is created, and everything else is as expected
queryset = NullableForeignKeySource.objects.all()
serializer = NullableForeignKeySourceSerializer(queryset, many=True)
expected = [
{'id': 1, 'name': 'source-1', 'target': 1},
{'id': 2, 'name': 'source-2', 'target': 1},
{'id': 3, 'name': 'source-3', 'target': None},
{'id': 4, 'name': 'source-4', 'target': None}
]
self.assertEqual(serializer.data, expected)
def test_foreign_key_create_with_valid_emptystring(self):
"""
The emptystring should be interpreted as null in the context
of relationships.
"""
data = {'id': 4, 'name': 'source-4', 'target': ''}
expected_data = {'id': 4, 'name': 'source-4', 'target': None}
serializer = NullableForeignKeySourceSerializer(data=data)
self.assertTrue(serializer.is_valid())
obj = serializer.save()
self.assertEqual(serializer.data, expected_data)
self.assertEqual(obj.name, 'source-4')
# Ensure source 4 is created, and everything else is as expected
queryset = NullableForeignKeySource.objects.all()
serializer = NullableForeignKeySourceSerializer(queryset, many=True)
expected = [
{'id': 1, 'name': 'source-1', 'target': 1},
{'id': 2, 'name': 'source-2', 'target': 1},
{'id': 3, 'name': 'source-3', 'target': None},
{'id': 4, 'name': 'source-4', 'target': None}
]
self.assertEqual(serializer.data, expected)
def test_foreign_key_update_with_valid_null(self):
data = {'id': 1, 'name': 'source-1', 'target': None}
instance = NullableForeignKeySource.objects.get(pk=1)
serializer = NullableForeignKeySourceSerializer(instance, data=data)
self.assertTrue(serializer.is_valid())
serializer.save()
self.assertEqual(serializer.data, data)
# Ensure source 1 is updated, and everything else is as expected
queryset = NullableForeignKeySource.objects.all()
serializer = NullableForeignKeySourceSerializer(queryset, many=True)
expected = [
{'id': 1, 'name': 'source-1', 'target': None},
{'id': 2, 'name': 'source-2', 'target': 1},
{'id': 3, 'name': 'source-3', 'target': None}
]
self.assertEqual(serializer.data, expected)
def test_foreign_key_update_with_valid_emptystring(self):
"""
The emptystring should be interpreted as null in the context
of relationships.
"""
data = {'id': 1, 'name': 'source-1', 'target': ''}
expected_data = {'id': 1, 'name': 'source-1', 'target': None}
instance = NullableForeignKeySource.objects.get(pk=1)
serializer = NullableForeignKeySourceSerializer(instance, data=data)
self.assertTrue(serializer.is_valid())
serializer.save()
self.assertEqual(serializer.data, expected_data)
# Ensure source 1 is updated, and everything else is as expected
queryset = NullableForeignKeySource.objects.all()
serializer = NullableForeignKeySourceSerializer(queryset, many=True)
expected = [
{'id': 1, 'name': 'source-1', 'target': None},
{'id': 2, 'name': 'source-2', 'target': 1},
{'id': 3, 'name': 'source-3', 'target': None}
]
self.assertEqual(serializer.data, expected)
# reverse foreign keys MUST be read_only
# In the general case they do not provide .remove() or .clear()
# and cannot be arbitrarily set.
# def test_reverse_foreign_key_update(self): # def test_reverse_foreign_key_update(self):
# data = {'id': 2, 'name': 'target-2', 'sources': [1, 3]} # data = {'id': 1, 'name': 'target-1', 'sources': [1]}
# instance = ForeignKeyTarget.objects.get(pk=2) # instance = ForeignKeyTarget.objects.get(pk=1)
# serializer = ForeignKeyTargetSerializer(instance, data=data) # serializer = ForeignKeyTargetSerializer(instance, data=data)
# self.assertTrue(serializer.is_valid()) # self.assertTrue(serializer.is_valid())
# # We shouldn't have saved anything to the db yet since save
# # hasn't been called.
# queryset = ForeignKeyTarget.objects.all()
# new_serializer = ForeignKeyTargetSerializer(queryset, many=True)
# expected = [
# {'id': 1, 'name': 'target-1', 'sources': [1, 2, 3]},
# {'id': 2, 'name': 'target-2', 'sources': []},
# ]
# self.assertEqual(new_serializer.data, expected)
# serializer.save()
# self.assertEqual(serializer.data, data) # self.assertEqual(serializer.data, data)
# serializer.save()
# # Ensure target 2 is update, and everything else is as expected # # Ensure target 1 is updated, and everything else is as expected
# queryset = ForeignKeyTarget.objects.all() # queryset = ForeignKeyTarget.objects.all()
# serializer = ForeignKeyTargetSerializer(queryset, many=True) # serializer = ForeignKeyTargetSerializer(queryset, many=True)
# expected = [ # expected = [
# {'id': 1, 'name': 'target-1', 'sources': [2]}, # {'id': 1, 'name': 'target-1', 'sources': [1]},
# {'id': 2, 'name': 'target-2', 'sources': [1, 3]},
# ]
# self.assertEqual(serializer.data, expected)
# def test_foreign_key_create(self):
# data = {'id': 4, 'name': 'source-4', 'target': 2}
# serializer = ForeignKeySourceSerializer(data=data)
# self.assertTrue(serializer.is_valid())
# obj = serializer.save()
# self.assertEqual(serializer.data, data)
# self.assertEqual(obj.name, 'source-4')
# # Ensure source 4 is added, and everything else is as expected
# queryset = ForeignKeySource.objects.all()
# serializer = ForeignKeySourceSerializer(queryset, many=True)
# expected = [
# {'id': 1, 'name': 'source-1', 'target': 1},
# {'id': 2, 'name': 'source-2', 'target': 1},
# {'id': 3, 'name': 'source-3', 'target': 1},
# {'id': 4, 'name': 'source-4', 'target': 2},
# ]
# self.assertEqual(serializer.data, expected)
# def test_reverse_foreign_key_create(self):
# data = {'id': 3, 'name': 'target-3', 'sources': [1, 3]}
# serializer = ForeignKeyTargetSerializer(data=data)
# self.assertTrue(serializer.is_valid())
# obj = serializer.save()
# self.assertEqual(serializer.data, data)
# self.assertEqual(obj.name, 'target-3')
# # Ensure target 3 is added, and everything else is as expected
# queryset = ForeignKeyTarget.objects.all()
# serializer = ForeignKeyTargetSerializer(queryset, many=True)
# expected = [
# {'id': 1, 'name': 'target-1', 'sources': [2]},
# {'id': 2, 'name': 'target-2', 'sources': []}, # {'id': 2, 'name': 'target-2', 'sources': []},
# {'id': 3, 'name': 'target-3', 'sources': [1, 3]},
# ]
# self.assertEqual(serializer.data, expected)
# def test_foreign_key_update_with_invalid_null(self):
# data = {'id': 1, 'name': 'source-1', 'target': None}
# instance = ForeignKeySource.objects.get(pk=1)
# serializer = ForeignKeySourceSerializer(instance, data=data)
# self.assertFalse(serializer.is_valid())
# self.assertEqual(serializer.errors, {'target': ['This field is required.']})
# def test_foreign_key_with_empty(self):
# """
# Regression test for #1072
# https://github.com/tomchristie/django-rest-framework/issues/1072
# """
# serializer = NullableForeignKeySourceSerializer()
# self.assertEqual(serializer.data['target'], None)
# class PKNullableForeignKeyTests(TestCase):
# def setUp(self):
# target = ForeignKeyTarget(name='target-1')
# target.save()
# for idx in range(1, 4):
# if idx == 3:
# target = None
# source = NullableForeignKeySource(name='source-%d' % idx, target=target)
# source.save()
# def test_foreign_key_retrieve_with_null(self):
# queryset = NullableForeignKeySource.objects.all()
# serializer = NullableForeignKeySourceSerializer(queryset, many=True)
# expected = [
# {'id': 1, 'name': 'source-1', 'target': 1},
# {'id': 2, 'name': 'source-2', 'target': 1},
# {'id': 3, 'name': 'source-3', 'target': None},
# ]
# self.assertEqual(serializer.data, expected)
# def test_foreign_key_create_with_valid_null(self):
# data = {'id': 4, 'name': 'source-4', 'target': None}
# serializer = NullableForeignKeySourceSerializer(data=data)
# self.assertTrue(serializer.is_valid())
# obj = serializer.save()
# self.assertEqual(serializer.data, data)
# self.assertEqual(obj.name, 'source-4')
# # Ensure source 4 is created, and everything else is as expected
# queryset = NullableForeignKeySource.objects.all()
# serializer = NullableForeignKeySourceSerializer(queryset, many=True)
# expected = [
# {'id': 1, 'name': 'source-1', 'target': 1},
# {'id': 2, 'name': 'source-2', 'target': 1},
# {'id': 3, 'name': 'source-3', 'target': None},
# {'id': 4, 'name': 'source-4', 'target': None}
# ]
# self.assertEqual(serializer.data, expected)
# def test_foreign_key_create_with_valid_emptystring(self):
# """
# The emptystring should be interpreted as null in the context
# of relationships.
# """
# data = {'id': 4, 'name': 'source-4', 'target': ''}
# expected_data = {'id': 4, 'name': 'source-4', 'target': None}
# serializer = NullableForeignKeySourceSerializer(data=data)
# self.assertTrue(serializer.is_valid())
# obj = serializer.save()
# self.assertEqual(serializer.data, expected_data)
# self.assertEqual(obj.name, 'source-4')
# # Ensure source 4 is created, and everything else is as expected
# queryset = NullableForeignKeySource.objects.all()
# serializer = NullableForeignKeySourceSerializer(queryset, many=True)
# expected = [
# {'id': 1, 'name': 'source-1', 'target': 1},
# {'id': 2, 'name': 'source-2', 'target': 1},
# {'id': 3, 'name': 'source-3', 'target': None},
# {'id': 4, 'name': 'source-4', 'target': None}
# ]
# self.assertEqual(serializer.data, expected)
# def test_foreign_key_update_with_valid_null(self):
# data = {'id': 1, 'name': 'source-1', 'target': None}
# instance = NullableForeignKeySource.objects.get(pk=1)
# serializer = NullableForeignKeySourceSerializer(instance, data=data)
# self.assertTrue(serializer.is_valid())
# self.assertEqual(serializer.data, data)
# serializer.save()
# # Ensure source 1 is updated, and everything else is as expected
# queryset = NullableForeignKeySource.objects.all()
# serializer = NullableForeignKeySourceSerializer(queryset, many=True)
# expected = [
# {'id': 1, 'name': 'source-1', 'target': None},
# {'id': 2, 'name': 'source-2', 'target': 1},
# {'id': 3, 'name': 'source-3', 'target': None}
# ]
# self.assertEqual(serializer.data, expected)
# def test_foreign_key_update_with_valid_emptystring(self):
# """
# The emptystring should be interpreted as null in the context
# of relationships.
# """
# data = {'id': 1, 'name': 'source-1', 'target': ''}
# expected_data = {'id': 1, 'name': 'source-1', 'target': None}
# instance = NullableForeignKeySource.objects.get(pk=1)
# serializer = NullableForeignKeySourceSerializer(instance, data=data)
# self.assertTrue(serializer.is_valid())
# self.assertEqual(serializer.data, expected_data)
# serializer.save()
# # Ensure source 1 is updated, and everything else is as expected
# queryset = NullableForeignKeySource.objects.all()
# serializer = NullableForeignKeySourceSerializer(queryset, many=True)
# expected = [
# {'id': 1, 'name': 'source-1', 'target': None},
# {'id': 2, 'name': 'source-2', 'target': 1},
# {'id': 3, 'name': 'source-3', 'target': None}
# ]
# self.assertEqual(serializer.data, expected)
# # reverse foreign keys MUST be read_only
# # In the general case they do not provide .remove() or .clear()
# # and cannot be arbitrarily set.
# # def test_reverse_foreign_key_update(self):
# # data = {'id': 1, 'name': 'target-1', 'sources': [1]}
# # instance = ForeignKeyTarget.objects.get(pk=1)
# # serializer = ForeignKeyTargetSerializer(instance, data=data)
# # self.assertTrue(serializer.is_valid())
# # self.assertEqual(serializer.data, data)
# # serializer.save()
# # # Ensure target 1 is updated, and everything else is as expected
# # queryset = ForeignKeyTarget.objects.all()
# # serializer = ForeignKeyTargetSerializer(queryset, many=True)
# # expected = [
# # {'id': 1, 'name': 'target-1', 'sources': [1]},
# # {'id': 2, 'name': 'target-2', 'sources': []},
# # ]
# # self.assertEqual(serializer.data, expected)
# class PKNullableOneToOneTests(TestCase):
# def setUp(self):
# target = OneToOneTarget(name='target-1')
# target.save()
# new_target = OneToOneTarget(name='target-2')
# new_target.save()
# 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': None},
# {'id': 2, 'name': 'target-2', 'nullable_source': 1},
# ] # ]
# self.assertEqual(serializer.data, expected) # self.assertEqual(serializer.data, expected)
# # The below models and tests ensure that serializer fields corresponding class PKNullableOneToOneTests(TestCase):
# # to a ManyToManyField field with a user-specified ``through`` model are def setUp(self):
# # set to read only target = OneToOneTarget(name='target-1')
target.save()
new_target = OneToOneTarget(name='target-2')
new_target.save()
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': None},
{'id': 2, 'name': 'target-2', 'nullable_source': 1},
]
self.assertEqual(serializer.data, expected)
# The below models and tests ensure that serializer fields corresponding
# to a ManyToManyField field with a user-specified ``through`` model are
# set to read only
# class ManyToManyThroughTarget(models.Model): # class ManyToManyThroughTarget(models.Model):
@ -481,7 +478,6 @@
# def test_many_to_many_create(self): # def test_many_to_many_create(self):
# data = {'id': 2, 'name': 'source-2', 'targets': [self.target.pk]} # data = {'id': 2, 'name': 'source-2', 'targets': [self.target.pk]}
# serializer = ManyToManyThroughSourceSerializer(data=data) # serializer = ManyToManyThroughSourceSerializer(data=data)
# self.assertTrue(serializer.fields['targets'].read_only)
# self.assertTrue(serializer.is_valid()) # self.assertTrue(serializer.is_valid())
# obj = serializer.save() # obj = serializer.save()
# self.assertEqual(obj.name, 'source-2') # self.assertEqual(obj.name, 'source-2')
@ -490,9 +486,7 @@
# def test_many_to_many_reverse_create(self): # def test_many_to_many_reverse_create(self):
# data = {'id': 2, 'name': 'target-2', 'sources': [self.source.pk]} # data = {'id': 2, 'name': 'target-2', 'sources': [self.source.pk]}
# serializer = ManyToManyThroughTargetSerializer(data=data) # serializer = ManyToManyThroughTargetSerializer(data=data)
# self.assertTrue(serializer.fields['sources'].read_only)
# self.assertTrue(serializer.is_valid()) # self.assertTrue(serializer.is_valid())
# serializer.save()
# obj = serializer.save() # obj = serializer.save()
# self.assertEqual(obj.name, 'target-2') # self.assertEqual(obj.name, 'target-2')
# self.assertEqual(obj.sources.count(), 0) # self.assertEqual(obj.sources.count(), 0)

View File

@ -1,257 +1,268 @@
# from django.test import TestCase from django.test import TestCase
# from rest_framework import serializers from rest_framework import serializers
# from tests.models import NullableForeignKeySource, ForeignKeySource, ForeignKeyTarget from tests.models import NullableForeignKeySource, ForeignKeySource, ForeignKeyTarget
# class ForeignKeyTargetSerializer(serializers.ModelSerializer): class ForeignKeyTargetSerializer(serializers.ModelSerializer):
# sources = serializers.SlugRelatedField(many=True, slug_field='name') sources = serializers.SlugRelatedField(
slug_field='name',
queryset=ForeignKeySource.objects.all(),
many=True
)
# class Meta: class Meta:
# model = ForeignKeyTarget model = ForeignKeyTarget
# class ForeignKeySourceSerializer(serializers.ModelSerializer): class ForeignKeySourceSerializer(serializers.ModelSerializer):
# target = serializers.SlugRelatedField(slug_field='name') target = serializers.SlugRelatedField(
slug_field='name',
queryset=ForeignKeyTarget.objects.all()
)
# class Meta: class Meta:
# model = ForeignKeySource model = ForeignKeySource
# class NullableForeignKeySourceSerializer(serializers.ModelSerializer): class NullableForeignKeySourceSerializer(serializers.ModelSerializer):
# target = serializers.SlugRelatedField(slug_field='name', required=False) target = serializers.SlugRelatedField(
slug_field='name',
queryset=ForeignKeyTarget.objects.all(),
allow_null=True
)
# class Meta: class Meta:
# model = NullableForeignKeySource model = NullableForeignKeySource
# # TODO: M2M Tests, FKTests (Non-nullable), One2One # TODO: M2M Tests, FKTests (Non-nullable), One2One
# class SlugForeignKeyTests(TestCase): class SlugForeignKeyTests(TestCase):
# def setUp(self): def setUp(self):
# target = ForeignKeyTarget(name='target-1') target = ForeignKeyTarget(name='target-1')
# target.save() target.save()
# new_target = ForeignKeyTarget(name='target-2') new_target = ForeignKeyTarget(name='target-2')
# new_target.save() new_target.save()
# for idx in range(1, 4): for idx in range(1, 4):
# source = ForeignKeySource(name='source-%d' % idx, target=target) source = ForeignKeySource(name='source-%d' % idx, target=target)
# source.save() source.save()
# def test_foreign_key_retrieve(self): def test_foreign_key_retrieve(self):
# queryset = ForeignKeySource.objects.all() queryset = ForeignKeySource.objects.all()
# serializer = ForeignKeySourceSerializer(queryset, many=True) serializer = ForeignKeySourceSerializer(queryset, many=True)
# expected = [ expected = [
# {'id': 1, 'name': 'source-1', 'target': 'target-1'}, {'id': 1, 'name': 'source-1', 'target': 'target-1'},
# {'id': 2, 'name': 'source-2', 'target': 'target-1'}, {'id': 2, 'name': 'source-2', 'target': 'target-1'},
# {'id': 3, 'name': 'source-3', 'target': 'target-1'} {'id': 3, 'name': 'source-3', 'target': 'target-1'}
# ] ]
# self.assertEqual(serializer.data, expected) self.assertEqual(serializer.data, expected)
# def test_reverse_foreign_key_retrieve(self): def test_reverse_foreign_key_retrieve(self):
# queryset = ForeignKeyTarget.objects.all() queryset = ForeignKeyTarget.objects.all()
# serializer = ForeignKeyTargetSerializer(queryset, many=True) serializer = ForeignKeyTargetSerializer(queryset, many=True)
# expected = [ expected = [
# {'id': 1, 'name': 'target-1', 'sources': ['source-1', 'source-2', 'source-3']}, {'id': 1, 'name': 'target-1', 'sources': ['source-1', 'source-2', 'source-3']},
# {'id': 2, 'name': 'target-2', 'sources': []}, {'id': 2, 'name': 'target-2', 'sources': []},
# ] ]
# self.assertEqual(serializer.data, expected) self.assertEqual(serializer.data, expected)
# def test_foreign_key_update(self): def test_foreign_key_update(self):
# data = {'id': 1, 'name': 'source-1', 'target': 'target-2'} data = {'id': 1, 'name': 'source-1', 'target': 'target-2'}
# instance = ForeignKeySource.objects.get(pk=1) instance = ForeignKeySource.objects.get(pk=1)
# serializer = ForeignKeySourceSerializer(instance, data=data) serializer = ForeignKeySourceSerializer(instance, data=data)
# self.assertTrue(serializer.is_valid()) self.assertTrue(serializer.is_valid())
# self.assertEqual(serializer.data, data) serializer.save()
# serializer.save() self.assertEqual(serializer.data, data)
# # Ensure source 1 is updated, and everything else is as expected # Ensure source 1 is updated, and everything else is as expected
# queryset = ForeignKeySource.objects.all() queryset = ForeignKeySource.objects.all()
# serializer = ForeignKeySourceSerializer(queryset, many=True) serializer = ForeignKeySourceSerializer(queryset, many=True)
# expected = [ expected = [
# {'id': 1, 'name': 'source-1', 'target': 'target-2'}, {'id': 1, 'name': 'source-1', 'target': 'target-2'},
# {'id': 2, 'name': 'source-2', 'target': 'target-1'}, {'id': 2, 'name': 'source-2', 'target': 'target-1'},
# {'id': 3, 'name': 'source-3', 'target': 'target-1'} {'id': 3, 'name': 'source-3', 'target': 'target-1'}
# ] ]
# self.assertEqual(serializer.data, expected) self.assertEqual(serializer.data, expected)
# def test_foreign_key_update_incorrect_type(self): def test_foreign_key_update_incorrect_type(self):
# data = {'id': 1, 'name': 'source-1', 'target': 123} data = {'id': 1, 'name': 'source-1', 'target': 123}
# instance = ForeignKeySource.objects.get(pk=1) instance = ForeignKeySource.objects.get(pk=1)
# serializer = ForeignKeySourceSerializer(instance, data=data) serializer = ForeignKeySourceSerializer(instance, data=data)
# self.assertFalse(serializer.is_valid()) self.assertFalse(serializer.is_valid())
# self.assertEqual(serializer.errors, {'target': ['Object with name=123 does not exist.']}) self.assertEqual(serializer.errors, {'target': ['Object with name=123 does not exist.']})
# def test_reverse_foreign_key_update(self): def test_reverse_foreign_key_update(self):
# data = {'id': 2, 'name': 'target-2', 'sources': ['source-1', 'source-3']} data = {'id': 2, 'name': 'target-2', 'sources': ['source-1', 'source-3']}
# instance = ForeignKeyTarget.objects.get(pk=2) instance = ForeignKeyTarget.objects.get(pk=2)
# serializer = ForeignKeyTargetSerializer(instance, data=data) serializer = ForeignKeyTargetSerializer(instance, data=data)
# self.assertTrue(serializer.is_valid()) self.assertTrue(serializer.is_valid())
# # We shouldn't have saved anything to the db yet since save # We shouldn't have saved anything to the db yet since save
# # hasn't been called. # hasn't been called.
# queryset = ForeignKeyTarget.objects.all() queryset = ForeignKeyTarget.objects.all()
# new_serializer = ForeignKeyTargetSerializer(queryset, many=True) new_serializer = ForeignKeyTargetSerializer(queryset, many=True)
# expected = [ expected = [
# {'id': 1, 'name': 'target-1', 'sources': ['source-1', 'source-2', 'source-3']}, {'id': 1, 'name': 'target-1', 'sources': ['source-1', 'source-2', 'source-3']},
# {'id': 2, 'name': 'target-2', 'sources': []}, {'id': 2, 'name': 'target-2', 'sources': []},
# ] ]
# self.assertEqual(new_serializer.data, expected) self.assertEqual(new_serializer.data, expected)
# serializer.save() serializer.save()
# self.assertEqual(serializer.data, data) self.assertEqual(serializer.data, data)
# # Ensure target 2 is update, and everything else is as expected # Ensure target 2 is update, and everything else is as expected
# queryset = ForeignKeyTarget.objects.all() queryset = ForeignKeyTarget.objects.all()
# serializer = ForeignKeyTargetSerializer(queryset, many=True) serializer = ForeignKeyTargetSerializer(queryset, many=True)
# expected = [ expected = [
# {'id': 1, 'name': 'target-1', 'sources': ['source-2']}, {'id': 1, 'name': 'target-1', 'sources': ['source-2']},
# {'id': 2, 'name': 'target-2', 'sources': ['source-1', 'source-3']}, {'id': 2, 'name': 'target-2', 'sources': ['source-1', 'source-3']},
# ] ]
# self.assertEqual(serializer.data, expected) self.assertEqual(serializer.data, expected)
# def test_foreign_key_create(self): def test_foreign_key_create(self):
# data = {'id': 4, 'name': 'source-4', 'target': 'target-2'} data = {'id': 4, 'name': 'source-4', 'target': 'target-2'}
# serializer = ForeignKeySourceSerializer(data=data) serializer = ForeignKeySourceSerializer(data=data)
# serializer.is_valid() serializer.is_valid()
# self.assertTrue(serializer.is_valid()) self.assertTrue(serializer.is_valid())
# obj = serializer.save() obj = serializer.save()
# self.assertEqual(serializer.data, data) self.assertEqual(serializer.data, data)
# self.assertEqual(obj.name, 'source-4') self.assertEqual(obj.name, 'source-4')
# # Ensure source 4 is added, and everything else is as expected # Ensure source 4 is added, and everything else is as expected
# queryset = ForeignKeySource.objects.all() queryset = ForeignKeySource.objects.all()
# serializer = ForeignKeySourceSerializer(queryset, many=True) serializer = ForeignKeySourceSerializer(queryset, many=True)
# expected = [ expected = [
# {'id': 1, 'name': 'source-1', 'target': 'target-1'}, {'id': 1, 'name': 'source-1', 'target': 'target-1'},
# {'id': 2, 'name': 'source-2', 'target': 'target-1'}, {'id': 2, 'name': 'source-2', 'target': 'target-1'},
# {'id': 3, 'name': 'source-3', 'target': 'target-1'}, {'id': 3, 'name': 'source-3', 'target': 'target-1'},
# {'id': 4, 'name': 'source-4', 'target': 'target-2'}, {'id': 4, 'name': 'source-4', 'target': 'target-2'},
# ] ]
# self.assertEqual(serializer.data, expected) self.assertEqual(serializer.data, expected)
# def test_reverse_foreign_key_create(self): def test_reverse_foreign_key_create(self):
# data = {'id': 3, 'name': 'target-3', 'sources': ['source-1', 'source-3']} data = {'id': 3, 'name': 'target-3', 'sources': ['source-1', 'source-3']}
# serializer = ForeignKeyTargetSerializer(data=data) serializer = ForeignKeyTargetSerializer(data=data)
# self.assertTrue(serializer.is_valid()) self.assertTrue(serializer.is_valid())
# obj = serializer.save() obj = serializer.save()
# self.assertEqual(serializer.data, data) self.assertEqual(serializer.data, data)
# self.assertEqual(obj.name, 'target-3') self.assertEqual(obj.name, 'target-3')
# # Ensure target 3 is added, and everything else is as expected # Ensure target 3 is added, and everything else is as expected
# queryset = ForeignKeyTarget.objects.all() queryset = ForeignKeyTarget.objects.all()
# serializer = ForeignKeyTargetSerializer(queryset, many=True) serializer = ForeignKeyTargetSerializer(queryset, many=True)
# expected = [ expected = [
# {'id': 1, 'name': 'target-1', 'sources': ['source-2']}, {'id': 1, 'name': 'target-1', 'sources': ['source-2']},
# {'id': 2, 'name': 'target-2', 'sources': []}, {'id': 2, 'name': 'target-2', 'sources': []},
# {'id': 3, 'name': 'target-3', 'sources': ['source-1', 'source-3']}, {'id': 3, 'name': 'target-3', 'sources': ['source-1', 'source-3']},
# ] ]
# self.assertEqual(serializer.data, expected) self.assertEqual(serializer.data, expected)
# def test_foreign_key_update_with_invalid_null(self): def test_foreign_key_update_with_invalid_null(self):
# data = {'id': 1, 'name': 'source-1', 'target': None} data = {'id': 1, 'name': 'source-1', 'target': None}
# instance = ForeignKeySource.objects.get(pk=1) instance = ForeignKeySource.objects.get(pk=1)
# serializer = ForeignKeySourceSerializer(instance, data=data) serializer = ForeignKeySourceSerializer(instance, data=data)
# self.assertFalse(serializer.is_valid()) self.assertFalse(serializer.is_valid())
# self.assertEqual(serializer.errors, {'target': ['This field is required.']}) self.assertEqual(serializer.errors, {'target': ['This field may not be null.']})
# class SlugNullableForeignKeyTests(TestCase): class SlugNullableForeignKeyTests(TestCase):
# def setUp(self): def setUp(self):
# target = ForeignKeyTarget(name='target-1') target = ForeignKeyTarget(name='target-1')
# target.save() target.save()
# for idx in range(1, 4): for idx in range(1, 4):
# if idx == 3: if idx == 3:
# target = None target = None
# source = NullableForeignKeySource(name='source-%d' % idx, target=target) source = NullableForeignKeySource(name='source-%d' % idx, target=target)
# source.save() source.save()
# def test_foreign_key_retrieve_with_null(self): def test_foreign_key_retrieve_with_null(self):
# queryset = NullableForeignKeySource.objects.all() queryset = NullableForeignKeySource.objects.all()
# serializer = NullableForeignKeySourceSerializer(queryset, many=True) serializer = NullableForeignKeySourceSerializer(queryset, many=True)
# expected = [ expected = [
# {'id': 1, 'name': 'source-1', 'target': 'target-1'}, {'id': 1, 'name': 'source-1', 'target': 'target-1'},
# {'id': 2, 'name': 'source-2', 'target': 'target-1'}, {'id': 2, 'name': 'source-2', 'target': 'target-1'},
# {'id': 3, 'name': 'source-3', 'target': None}, {'id': 3, 'name': 'source-3', 'target': None},
# ] ]
# self.assertEqual(serializer.data, expected) self.assertEqual(serializer.data, expected)
# def test_foreign_key_create_with_valid_null(self): def test_foreign_key_create_with_valid_null(self):
# data = {'id': 4, 'name': 'source-4', 'target': None} data = {'id': 4, 'name': 'source-4', 'target': None}
# serializer = NullableForeignKeySourceSerializer(data=data) serializer = NullableForeignKeySourceSerializer(data=data)
# self.assertTrue(serializer.is_valid()) self.assertTrue(serializer.is_valid())
# obj = serializer.save() obj = serializer.save()
# self.assertEqual(serializer.data, data) self.assertEqual(serializer.data, data)
# self.assertEqual(obj.name, 'source-4') self.assertEqual(obj.name, 'source-4')
# # Ensure source 4 is created, and everything else is as expected # Ensure source 4 is created, and everything else is as expected
# queryset = NullableForeignKeySource.objects.all() queryset = NullableForeignKeySource.objects.all()
# serializer = NullableForeignKeySourceSerializer(queryset, many=True) serializer = NullableForeignKeySourceSerializer(queryset, many=True)
# expected = [ expected = [
# {'id': 1, 'name': 'source-1', 'target': 'target-1'}, {'id': 1, 'name': 'source-1', 'target': 'target-1'},
# {'id': 2, 'name': 'source-2', 'target': 'target-1'}, {'id': 2, 'name': 'source-2', 'target': 'target-1'},
# {'id': 3, 'name': 'source-3', 'target': None}, {'id': 3, 'name': 'source-3', 'target': None},
# {'id': 4, 'name': 'source-4', 'target': None} {'id': 4, 'name': 'source-4', 'target': None}
# ] ]
# self.assertEqual(serializer.data, expected) self.assertEqual(serializer.data, expected)
# def test_foreign_key_create_with_valid_emptystring(self): def test_foreign_key_create_with_valid_emptystring(self):
# """ """
# The emptystring should be interpreted as null in the context The emptystring should be interpreted as null in the context
# of relationships. of relationships.
# """ """
# data = {'id': 4, 'name': 'source-4', 'target': ''} data = {'id': 4, 'name': 'source-4', 'target': ''}
# expected_data = {'id': 4, 'name': 'source-4', 'target': None} expected_data = {'id': 4, 'name': 'source-4', 'target': None}
# serializer = NullableForeignKeySourceSerializer(data=data) serializer = NullableForeignKeySourceSerializer(data=data)
# self.assertTrue(serializer.is_valid()) self.assertTrue(serializer.is_valid())
# obj = serializer.save() obj = serializer.save()
# self.assertEqual(serializer.data, expected_data) self.assertEqual(serializer.data, expected_data)
# self.assertEqual(obj.name, 'source-4') self.assertEqual(obj.name, 'source-4')
# # Ensure source 4 is created, and everything else is as expected # Ensure source 4 is created, and everything else is as expected
# queryset = NullableForeignKeySource.objects.all() queryset = NullableForeignKeySource.objects.all()
# serializer = NullableForeignKeySourceSerializer(queryset, many=True) serializer = NullableForeignKeySourceSerializer(queryset, many=True)
# expected = [ expected = [
# {'id': 1, 'name': 'source-1', 'target': 'target-1'}, {'id': 1, 'name': 'source-1', 'target': 'target-1'},
# {'id': 2, 'name': 'source-2', 'target': 'target-1'}, {'id': 2, 'name': 'source-2', 'target': 'target-1'},
# {'id': 3, 'name': 'source-3', 'target': None}, {'id': 3, 'name': 'source-3', 'target': None},
# {'id': 4, 'name': 'source-4', 'target': None} {'id': 4, 'name': 'source-4', 'target': None}
# ] ]
# self.assertEqual(serializer.data, expected) self.assertEqual(serializer.data, expected)
# def test_foreign_key_update_with_valid_null(self): def test_foreign_key_update_with_valid_null(self):
# data = {'id': 1, 'name': 'source-1', 'target': None} data = {'id': 1, 'name': 'source-1', 'target': None}
# instance = NullableForeignKeySource.objects.get(pk=1) instance = NullableForeignKeySource.objects.get(pk=1)
# serializer = NullableForeignKeySourceSerializer(instance, data=data) serializer = NullableForeignKeySourceSerializer(instance, data=data)
# self.assertTrue(serializer.is_valid()) self.assertTrue(serializer.is_valid())
# self.assertEqual(serializer.data, data) serializer.save()
# serializer.save() self.assertEqual(serializer.data, data)
# # Ensure source 1 is updated, and everything else is as expected # Ensure source 1 is updated, and everything else is as expected
# queryset = NullableForeignKeySource.objects.all() queryset = NullableForeignKeySource.objects.all()
# serializer = NullableForeignKeySourceSerializer(queryset, many=True) serializer = NullableForeignKeySourceSerializer(queryset, many=True)
# expected = [ expected = [
# {'id': 1, 'name': 'source-1', 'target': None}, {'id': 1, 'name': 'source-1', 'target': None},
# {'id': 2, 'name': 'source-2', 'target': 'target-1'}, {'id': 2, 'name': 'source-2', 'target': 'target-1'},
# {'id': 3, 'name': 'source-3', 'target': None} {'id': 3, 'name': 'source-3', 'target': None}
# ] ]
# self.assertEqual(serializer.data, expected) self.assertEqual(serializer.data, expected)
# def test_foreign_key_update_with_valid_emptystring(self): def test_foreign_key_update_with_valid_emptystring(self):
# """ """
# The emptystring should be interpreted as null in the context The emptystring should be interpreted as null in the context
# of relationships. of relationships.
# """ """
# data = {'id': 1, 'name': 'source-1', 'target': ''} data = {'id': 1, 'name': 'source-1', 'target': ''}
# expected_data = {'id': 1, 'name': 'source-1', 'target': None} expected_data = {'id': 1, 'name': 'source-1', 'target': None}
# instance = NullableForeignKeySource.objects.get(pk=1) instance = NullableForeignKeySource.objects.get(pk=1)
# serializer = NullableForeignKeySourceSerializer(instance, data=data) serializer = NullableForeignKeySourceSerializer(instance, data=data)
# self.assertTrue(serializer.is_valid()) self.assertTrue(serializer.is_valid())
# self.assertEqual(serializer.data, expected_data) serializer.save()
# serializer.save() self.assertEqual(serializer.data, expected_data)
# # Ensure source 1 is updated, and everything else is as expected # Ensure source 1 is updated, and everything else is as expected
# queryset = NullableForeignKeySource.objects.all() queryset = NullableForeignKeySource.objects.all()
# serializer = NullableForeignKeySourceSerializer(queryset, many=True) serializer = NullableForeignKeySourceSerializer(queryset, many=True)
# expected = [ expected = [
# {'id': 1, 'name': 'source-1', 'target': None}, {'id': 1, 'name': 'source-1', 'target': None},
# {'id': 2, 'name': 'source-2', 'target': 'target-1'}, {'id': 2, 'name': 'source-2', 'target': 'target-1'},
# {'id': 3, 'name': 'source-3', 'target': None} {'id': 3, 'name': 'source-3', 'target': None}
# ] ]
# self.assertEqual(serializer.data, expected) self.assertEqual(serializer.data, expected)