Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
D
django-rest-framework
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
django-rest-framework
Commits
093febb9
Commit
093febb9
authored
Oct 08, 2014
by
Tom Christie
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Tests for relational fields
parent
3fa4a189
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
1168 additions
and
1155 deletions
+1168
-1155
rest_framework/fields.py
+8
-1
tests/test_relations_hyperlink.py
+452
-451
tests/test_relations_pk.py
+440
-446
tests/test_relations_slug.py
+268
-257
No files found.
rest_framework/fields.py
View file @
093febb9
from
django
import
forms
from
django.conf
import
settings
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.datastructures
import
SortedDict
from
django.utils.dateparse
import
parse_date
,
parse_datetime
,
parse_time
...
...
@@ -54,6 +54,8 @@ def get_attribute(instance, attrs):
for
attr
in
attrs
:
try
:
instance
=
getattr
(
instance
,
attr
)
except
ObjectDoesNotExist
:
return
None
except
AttributeError
as
exc
:
try
:
return
instance
[
attr
]
...
...
@@ -108,6 +110,7 @@ class Field(object):
default_validators
=
[]
default_empty_html
=
empty
initial
=
None
coerce_blank_to_null
=
True
def
__init__
(
self
,
read_only
=
False
,
write_only
=
False
,
required
=
None
,
default
=
empty
,
initial
=
empty
,
source
=
None
,
...
...
@@ -245,6 +248,9 @@ class Field(object):
self
.
fail
(
'required'
)
return
self
.
get_default
()
if
data
==
''
and
self
.
coerce_blank_to_null
:
data
=
None
if
data
is
None
:
if
not
self
.
allow_null
:
self
.
fail
(
'null'
)
...
...
@@ -413,6 +419,7 @@ class CharField(Field):
'blank'
:
_
(
'This field may not be blank.'
)
}
initial
=
''
coerce_blank_to_null
=
False
def
__init__
(
self
,
**
kwargs
):
self
.
allow_blank
=
kwargs
.
pop
(
'allow_blank'
,
False
)
...
...
tests/test_relations_hyperlink.py
View file @
093febb9
# from __future__ import unicode_literals
# from django.conf.urls import patterns, url
# from django.test import TestCase
# from rest_framework import serializers
# from rest_framework.test import APIRequestFactory
# from tests.models import (
# BlogPost,
# ManyToManyTarget, ManyToManySource, ForeignKeyTarget, ForeignKeySource,
# NullableForeignKeySource, OneToOneTarget, NullableOneToOneSource
# )
# factory = APIRequestFactory()
# request = factory.get('/') # Just to ensure we have a request in the serializer context
# def dummy_view(request, pk):
# pass
# urlpatterns = patterns(
# '',
# 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'^manytomanytarget/(?P<pk>[0-9]+)/$', dummy_view, name='manytomanytarget-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'^nullableforeignkeysource/(?P<pk>[0-9]+)/$', dummy_view, name='nullableforeignkeysource-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'),
# )
# # ManyToMany
# class ManyToManyTargetSerializer(serializers.HyperlinkedModelSerializer):
# class Meta:
# model = ManyToManyTarget
# fields = ('url', 'name', 'sources')
# class ManyToManySourceSerializer(serializers.HyperlinkedModelSerializer):
# class Meta:
# model = ManyToManySource
# fields = ('url', 'name', 'targets')
# # ForeignKey
# class ForeignKeyTargetSerializer(serializers.HyperlinkedModelSerializer):
# class Meta:
# model = ForeignKeyTarget
# fields = ('url', 'name', 'sources')
# class ForeignKeySourceSerializer(serializers.HyperlinkedModelSerializer):
# class Meta:
# model = ForeignKeySource
# fields = ('url', 'name', 'target')
# # Nullable ForeignKey
# class NullableForeignKeySourceSerializer(serializers.HyperlinkedModelSerializer):
# class Meta:
# model = NullableForeignKeySource
# fields = ('url', 'name', 'target')
# # Nullable OneToOne
# class NullableOneToOneTargetSerializer(serializers.HyperlinkedModelSerializer):
# class Meta:
# model = OneToOneTarget
# fields = ('url', 'name', 'nullable_source')
# # TODO: Add test that .data cannot be accessed prior to .is_valid
# class HyperlinkedManyToManyTests(TestCase):
# urls = 'tests.test_relations_hyperlink'
# def setUp(self):
# for idx in range(1, 4):
# target = ManyToManyTarget(name='target-%d' % idx)
# target.save()
# source = ManyToManySource(name='source-%d' % idx)
# source.save()
# for target in ManyToManyTarget.objects.all():
# source.targets.add(target)
# def test_many_to_many_retrieve(self):
# queryset = ManyToManySource.objects.all()
# serializer = ManyToManySourceSerializer(queryset, many=True, context={'request': request})
# expected = [
# {'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/3/', 'name': 'source-3', 'targets': ['http://testserver/manytomanytarget/1/', 'http://testserver/manytomanytarget/2/', 'http://testserver/manytomanytarget/3/']}
# ]
# self.assertEqual(serializer.data, expected)
# def test_reverse_many_to_many_retrieve(self):
# queryset = ManyToManyTarget.objects.all()
# serializer = ManyToManyTargetSerializer(queryset, many=True, context={'request': request})
# 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/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/']}
# ]
# self.assertEqual(serializer.data, expected)
# 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/']}
# instance = ManyToManySource.objects.get(pk=1)
# serializer = ManyToManySourceSerializer(instance, data=data, context={'request': request})
# self.assertTrue(serializer.is_valid())
# serializer.save()
# self.assertEqual(serializer.data, data)
# # Ensure source 1 is updated, and everything else is as expected
# queryset = ManyToManySource.objects.all()
# serializer = ManyToManySourceSerializer(queryset, many=True, context={'request': request})
# 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/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/']}
# ]
# self.assertEqual(serializer.data, expected)
# def test_reverse_many_to_many_update(self):
# data = {'url': 'http://testserver/manytomanytarget/1/', 'name': 'target-1', 'sources': ['http://testserver/manytomanysource/1/']}
# instance = ManyToManyTarget.objects.get(pk=1)
# serializer = ManyToManyTargetSerializer(instance, data=data, context={'request': request})
# self.assertTrue(serializer.is_valid())
# serializer.save()
# self.assertEqual(serializer.data, data)
# # Ensure target 1 is updated, and everything else is as expected
# queryset = ManyToManyTarget.objects.all()
# serializer = ManyToManyTargetSerializer(queryset, many=True, context={'request': request})
# expected = [
# {'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/3/', 'name': 'target-3', 'sources': ['http://testserver/manytomanysource/3/']}
# ]
# self.assertEqual(serializer.data, expected)
# 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/']}
# serializer = ManyToManySourceSerializer(data=data, context={'request': request})
# 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 = ManyToManySource.objects.all()
# serializer = ManyToManySourceSerializer(queryset, many=True, context={'request': request})
# expected = [
# {'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/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/']}
# ]
# self.assertEqual(serializer.data, expected)
# 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/']}
# serializer = ManyToManyTargetSerializer(data=data, context={'request': request})
# self.assertTrue(serializer.is_valid())
# obj = serializer.save()
# self.assertEqual(serializer.data, data)
# self.assertEqual(obj.name, 'target-4')
# # Ensure target 4 is added, and everything else is as expected
# queryset = ManyToManyTarget.objects.all()
# serializer = ManyToManyTargetSerializer(queryset, many=True, context={'request': request})
# 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/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/4/', 'name': 'target-4', 'sources': ['http://testserver/manytomanysource/1/', 'http://testserver/manytomanysource/3/']}
# ]
# self.assertEqual(serializer.data, expected)
# class HyperlinkedForeignKeyTests(TestCase):
# urls = 'tests.test_relations_hyperlink'
# def setUp(self):
# target = ForeignKeyTarget(name='target-1')
# target.save()
# new_target = ForeignKeyTarget(name='target-2')
# new_target.save()
# for idx in range(1, 4):
# source = ForeignKeySource(name='source-%d' % idx, target=target)
# source.save()
# def test_foreign_key_retrieve(self):
# queryset = ForeignKeySource.objects.all()
# serializer = ForeignKeySourceSerializer(queryset, many=True, context={'request': request})
# expected = [
# {'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/3/', 'name': 'source-3', 'target': 'http://testserver/foreignkeytarget/1/'}
# ]
# self.assertEqual(serializer.data, expected)
# def test_reverse_foreign_key_retrieve(self):
# queryset = ForeignKeyTarget.objects.all()
# serializer = ForeignKeyTargetSerializer(queryset, many=True, context={'request': request})
# 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/2/', 'name': 'target-2', 'sources': []},
# ]
# self.assertEqual(serializer.data, expected)
# def test_foreign_key_update(self):
# data = {'url': 'http://testserver/foreignkeysource/1/', 'name': 'source-1', 'target': 'http://testserver/foreignkeytarget/2/'}
# instance = ForeignKeySource.objects.get(pk=1)
# serializer = ForeignKeySourceSerializer(instance, data=data, context={'request': request})
# self.assertTrue(serializer.is_valid())
# self.assertEqual(serializer.data, data)
# serializer.save()
# # Ensure source 1 is updated, and everything else is as expected
# queryset = ForeignKeySource.objects.all()
# serializer = ForeignKeySourceSerializer(queryset, many=True, context={'request': request})
# expected = [
# {'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/3/', 'name': 'source-3', 'target': 'http://testserver/foreignkeytarget/1/'}
# ]
# self.assertEqual(serializer.data, expected)
# def test_foreign_key_update_incorrect_type(self):
# data = {'url': 'http://testserver/foreignkeysource/1/', 'name': 'source-1', 'target': 2}
# instance = ForeignKeySource.objects.get(pk=1)
# serializer = ForeignKeySourceSerializer(instance, data=data, context={'request': request})
# self.assertFalse(serializer.is_valid())
# self.assertEqual(serializer.errors, {'target': ['Incorrect type. Expected url string, received int.']})
# 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/']}
# instance = ForeignKeyTarget.objects.get(pk=2)
# serializer = ForeignKeyTargetSerializer(instance, data=data, context={'request': request})
# 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, context={'request': request})
# 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/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, context={'request': request})
# expected = [
# {'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/']},
# ]
# self.assertEqual(serializer.data, expected)
# def test_foreign_key_create(self):
# data = {'url': 'http://testserver/foreignkeysource/4/', 'name': 'source-4', 'target': 'http://testserver/foreignkeytarget/2/'}
# serializer = ForeignKeySourceSerializer(data=data, context={'request': request})
# self.assertTrue(serializer.is_valid())
# obj = serializer.save()
# self.assertEqual(serializer.data, data)
# self.assertEqual(obj.name, 'source-4')
# # Ensure source 1 is updated, and everything else is as expected
# queryset = ForeignKeySource.objects.all()
# serializer = ForeignKeySourceSerializer(queryset, many=True, context={'request': request})
# expected = [
# {'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/3/', 'name': 'source-3', 'target': 'http://testserver/foreignkeytarget/1/'},
# {'url': 'http://testserver/foreignkeysource/4/', 'name': 'source-4', 'target': 'http://testserver/foreignkeytarget/2/'},
# ]
# self.assertEqual(serializer.data, expected)
# 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/']}
# serializer = ForeignKeyTargetSerializer(data=data, context={'request': request})
# self.assertTrue(serializer.is_valid())
# obj = serializer.save()
# self.assertEqual(serializer.data, data)
# self.assertEqual(obj.name, 'target-3')
# # Ensure target 4 is added, and everything else is as expected
# queryset = ForeignKeyTarget.objects.all()
# serializer = ForeignKeyTargetSerializer(queryset, many=True, context={'request': request})
# expected = [
# {'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/3/', 'name': 'target-3', 'sources': ['http://testserver/foreignkeysource/1/', 'http://testserver/foreignkeysource/3/']},
# ]
# self.assertEqual(serializer.data, expected)
# def test_foreign_key_update_with_invalid_null(self):
# data = {'url': 'http://testserver/foreignkeysource/1/', 'name': 'source-1', 'target': None}
# instance = ForeignKeySource.objects.get(pk=1)
# serializer = ForeignKeySourceSerializer(instance, data=data, context={'request': request})
# self.assertFalse(serializer.is_valid())
# self.assertEqual(serializer.errors, {'target': ['This field is required.']})
# class HyperlinkedNullableForeignKeyTests(TestCase):
# urls = 'tests.test_relations_hyperlink'
# 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, context={'request': request})
# expected = [
# {'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/3/', 'name': 'source-3', 'target': None},
# ]
# self.assertEqual(serializer.data, expected)
# def test_foreign_key_create_with_valid_null(self):
# data = {'url': 'http://testserver/nullableforeignkeysource/4/', 'name': 'source-4', 'target': None}
# serializer = NullableForeignKeySourceSerializer(data=data, context={'request': request})
# 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, context={'request': request})
# expected = [
# {'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/3/', 'name': 'source-3', 'target': None},
# {'url': 'http://testserver/nullableforeignkeysource/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 = {'url': 'http://testserver/nullableforeignkeysource/4/', 'name': 'source-4', 'target': ''}
# expected_data = {'url': 'http://testserver/nullableforeignkeysource/4/', 'name': 'source-4', 'target': None}
# serializer = NullableForeignKeySourceSerializer(data=data, context={'request': request})
# 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, context={'request': request})
# expected = [
# {'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/3/', 'name': 'source-3', 'target': None},
# {'url': 'http://testserver/nullableforeignkeysource/4/', 'name': 'source-4', 'target': None}
# ]
# self.assertEqual(serializer.data, expected)
# def test_foreign_key_update_with_valid_null(self):
# data = {'url': 'http://testserver/nullableforeignkeysource/1/', 'name': 'source-1', 'target': None}
# instance = NullableForeignKeySource.objects.get(pk=1)
# serializer = NullableForeignKeySourceSerializer(instance, data=data, context={'request': request})
# 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, context={'request': request})
# expected = [
# {'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/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 = {'url': 'http://testserver/nullableforeignkeysource/1/', 'name': 'source-1', 'target': ''}
# expected_data = {'url': 'http://testserver/nullableforeignkeysource/1/', 'name': 'source-1', 'target': None}
# instance = NullableForeignKeySource.objects.get(pk=1)
# serializer = NullableForeignKeySourceSerializer(instance, data=data, context={'request': request})
# 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, context={'request': request})
# expected = [
# {'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/3/', 'name': 'source-3', 'target': None},
# ]
# self.assertEqual(serializer.data, expected)
from
__future__
import
unicode_literals
from
django.conf.urls
import
patterns
,
url
from
django.test
import
TestCase
from
rest_framework
import
serializers
from
rest_framework.test
import
APIRequestFactory
from
tests.models
import
(
ManyToManyTarget
,
ManyToManySource
,
ForeignKeyTarget
,
ForeignKeySource
,
NullableForeignKeySource
,
OneToOneTarget
,
NullableOneToOneSource
)
factory
=
APIRequestFactory
()
request
=
factory
.
get
(
'/'
)
# Just to ensure we have a request in the serializer context
dummy_view
=
lambda
request
,
pk
:
None
urlpatterns
=
patterns
(
''
,
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'^manytomanytarget/(?P<pk>[0-9]+)/$'
,
dummy_view
,
name
=
'manytomanytarget-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'^nullableforeignkeysource/(?P<pk>[0-9]+)/$'
,
dummy_view
,
name
=
'nullableforeignkeysource-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'
),
)
# ManyToMany
class
ManyToManyTargetSerializer
(
serializers
.
HyperlinkedModelSerializer
):
class
Meta
:
model
=
ManyToManyTarget
fields
=
(
'url'
,
'name'
,
'sources'
)
class
ManyToManySourceSerializer
(
serializers
.
HyperlinkedModelSerializer
):
class
Meta
:
model
=
ManyToManySource
fields
=
(
'url'
,
'name'
,
'targets'
)
# ForeignKey
class
ForeignKeyTargetSerializer
(
serializers
.
HyperlinkedModelSerializer
):
class
Meta
:
model
=
ForeignKeyTarget
fields
=
(
'url'
,
'name'
,
'sources'
)
class
ForeignKeySourceSerializer
(
serializers
.
HyperlinkedModelSerializer
):
class
Meta
:
model
=
ForeignKeySource
fields
=
(
'url'
,
'name'
,
'target'
)
# Nullable ForeignKey
class
NullableForeignKeySourceSerializer
(
serializers
.
HyperlinkedModelSerializer
):
class
Meta
:
model
=
NullableForeignKeySource
fields
=
(
'url'
,
'name'
,
'target'
)
# Nullable OneToOne
class
NullableOneToOneTargetSerializer
(
serializers
.
HyperlinkedModelSerializer
):
class
Meta
:
model
=
OneToOneTarget
fields
=
(
'url'
,
'name'
,
'nullable_source'
)
# TODO: Add test that .data cannot be accessed prior to .is_valid
class
HyperlinkedManyToManyTests
(
TestCase
):
urls
=
'tests.test_relations_hyperlink'
def
setUp
(
self
):
for
idx
in
range
(
1
,
4
):
target
=
ManyToManyTarget
(
name
=
'target-
%
d'
%
idx
)
target
.
save
()
source
=
ManyToManySource
(
name
=
'source-
%
d'
%
idx
)
source
.
save
()
for
target
in
ManyToManyTarget
.
objects
.
all
():
source
.
targets
.
add
(
target
)
def
test_many_to_many_retrieve
(
self
):
queryset
=
ManyToManySource
.
objects
.
all
()
serializer
=
ManyToManySourceSerializer
(
queryset
,
many
=
True
,
context
=
{
'request'
:
request
})
expected
=
[
{
'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/3/'
,
'name'
:
'source-3'
,
'targets'
:
[
'http://testserver/manytomanytarget/1/'
,
'http://testserver/manytomanytarget/2/'
,
'http://testserver/manytomanytarget/3/'
]}
]
self
.
assertEqual
(
serializer
.
data
,
expected
)
def
test_reverse_many_to_many_retrieve
(
self
):
queryset
=
ManyToManyTarget
.
objects
.
all
()
serializer
=
ManyToManyTargetSerializer
(
queryset
,
many
=
True
,
context
=
{
'request'
:
request
})
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/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/'
]}
]
self
.
assertEqual
(
serializer
.
data
,
expected
)
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/'
]}
instance
=
ManyToManySource
.
objects
.
get
(
pk
=
1
)
serializer
=
ManyToManySourceSerializer
(
instance
,
data
=
data
,
context
=
{
'request'
:
request
})
self
.
assertTrue
(
serializer
.
is_valid
())
serializer
.
save
()
self
.
assertEqual
(
serializer
.
data
,
data
)
# Ensure source 1 is updated, and everything else is as expected
queryset
=
ManyToManySource
.
objects
.
all
()
serializer
=
ManyToManySourceSerializer
(
queryset
,
many
=
True
,
context
=
{
'request'
:
request
})
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/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/'
]}
]
self
.
assertEqual
(
serializer
.
data
,
expected
)
def
test_reverse_many_to_many_update
(
self
):
data
=
{
'url'
:
'http://testserver/manytomanytarget/1/'
,
'name'
:
'target-1'
,
'sources'
:
[
'http://testserver/manytomanysource/1/'
]}
instance
=
ManyToManyTarget
.
objects
.
get
(
pk
=
1
)
serializer
=
ManyToManyTargetSerializer
(
instance
,
data
=
data
,
context
=
{
'request'
:
request
})
self
.
assertTrue
(
serializer
.
is_valid
())
serializer
.
save
()
self
.
assertEqual
(
serializer
.
data
,
data
)
# Ensure target 1 is updated, and everything else is as expected
queryset
=
ManyToManyTarget
.
objects
.
all
()
serializer
=
ManyToManyTargetSerializer
(
queryset
,
many
=
True
,
context
=
{
'request'
:
request
})
expected
=
[
{
'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/3/'
,
'name'
:
'target-3'
,
'sources'
:
[
'http://testserver/manytomanysource/3/'
]}
]
self
.
assertEqual
(
serializer
.
data
,
expected
)
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/'
]}
serializer
=
ManyToManySourceSerializer
(
data
=
data
,
context
=
{
'request'
:
request
})
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
=
ManyToManySource
.
objects
.
all
()
serializer
=
ManyToManySourceSerializer
(
queryset
,
many
=
True
,
context
=
{
'request'
:
request
})
expected
=
[
{
'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/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/'
]}
]
self
.
assertEqual
(
serializer
.
data
,
expected
)
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/'
]}
serializer
=
ManyToManyTargetSerializer
(
data
=
data
,
context
=
{
'request'
:
request
})
self
.
assertTrue
(
serializer
.
is_valid
())
obj
=
serializer
.
save
()
self
.
assertEqual
(
serializer
.
data
,
data
)
self
.
assertEqual
(
obj
.
name
,
'target-4'
)
# Ensure target 4 is added, and everything else is as expected
queryset
=
ManyToManyTarget
.
objects
.
all
()
serializer
=
ManyToManyTargetSerializer
(
queryset
,
many
=
True
,
context
=
{
'request'
:
request
})
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/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/4/'
,
'name'
:
'target-4'
,
'sources'
:
[
'http://testserver/manytomanysource/1/'
,
'http://testserver/manytomanysource/3/'
]}
]
self
.
assertEqual
(
serializer
.
data
,
expected
)
class
HyperlinkedForeignKeyTests
(
TestCase
):
urls
=
'tests.test_relations_hyperlink'
def
setUp
(
self
):
target
=
ForeignKeyTarget
(
name
=
'target-1'
)
target
.
save
()
new_target
=
ForeignKeyTarget
(
name
=
'target-2'
)
new_target
.
save
()
for
idx
in
range
(
1
,
4
):
source
=
ForeignKeySource
(
name
=
'source-
%
d'
%
idx
,
target
=
target
)
source
.
save
()
def
test_foreign_key_retrieve
(
self
):
queryset
=
ForeignKeySource
.
objects
.
all
()
serializer
=
ForeignKeySourceSerializer
(
queryset
,
many
=
True
,
context
=
{
'request'
:
request
})
expected
=
[
{
'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/3/'
,
'name'
:
'source-3'
,
'target'
:
'http://testserver/foreignkeytarget/1/'
}
]
self
.
assertEqual
(
serializer
.
data
,
expected
)
def
test_reverse_foreign_key_retrieve
(
self
):
queryset
=
ForeignKeyTarget
.
objects
.
all
()
serializer
=
ForeignKeyTargetSerializer
(
queryset
,
many
=
True
,
context
=
{
'request'
:
request
})
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/2/'
,
'name'
:
'target-2'
,
'sources'
:
[]},
]
self
.
assertEqual
(
serializer
.
data
,
expected
)
def
test_foreign_key_update
(
self
):
data
=
{
'url'
:
'http://testserver/foreignkeysource/1/'
,
'name'
:
'source-1'
,
'target'
:
'http://testserver/foreignkeytarget/2/'
}
instance
=
ForeignKeySource
.
objects
.
get
(
pk
=
1
)
serializer
=
ForeignKeySourceSerializer
(
instance
,
data
=
data
,
context
=
{
'request'
:
request
})
self
.
assertTrue
(
serializer
.
is_valid
())
serializer
.
save
()
self
.
assertEqual
(
serializer
.
data
,
data
)
# Ensure source 1 is updated, and everything else is as expected
queryset
=
ForeignKeySource
.
objects
.
all
()
serializer
=
ForeignKeySourceSerializer
(
queryset
,
many
=
True
,
context
=
{
'request'
:
request
})
expected
=
[
{
'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/3/'
,
'name'
:
'source-3'
,
'target'
:
'http://testserver/foreignkeytarget/1/'
}
]
self
.
assertEqual
(
serializer
.
data
,
expected
)
def
test_foreign_key_update_incorrect_type
(
self
):
data
=
{
'url'
:
'http://testserver/foreignkeysource/1/'
,
'name'
:
'source-1'
,
'target'
:
2
}
instance
=
ForeignKeySource
.
objects
.
get
(
pk
=
1
)
serializer
=
ForeignKeySourceSerializer
(
instance
,
data
=
data
,
context
=
{
'request'
:
request
})
self
.
assertFalse
(
serializer
.
is_valid
())
self
.
assertEqual
(
serializer
.
errors
,
{
'target'
:
[
'Incorrect type. Expected URL string, received int.'
]})
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/'
]}
instance
=
ForeignKeyTarget
.
objects
.
get
(
pk
=
2
)
serializer
=
ForeignKeyTargetSerializer
(
instance
,
data
=
data
,
context
=
{
'request'
:
request
})
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
,
context
=
{
'request'
:
request
})
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/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
,
context
=
{
'request'
:
request
})
expected
=
[
{
'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/'
]},
]
self
.
assertEqual
(
serializer
.
data
,
expected
)
def
test_foreign_key_create
(
self
):
data
=
{
'url'
:
'http://testserver/foreignkeysource/4/'
,
'name'
:
'source-4'
,
'target'
:
'http://testserver/foreignkeytarget/2/'
}
serializer
=
ForeignKeySourceSerializer
(
data
=
data
,
context
=
{
'request'
:
request
})
self
.
assertTrue
(
serializer
.
is_valid
())
obj
=
serializer
.
save
()
self
.
assertEqual
(
serializer
.
data
,
data
)
self
.
assertEqual
(
obj
.
name
,
'source-4'
)
# Ensure source 1 is updated, and everything else is as expected
queryset
=
ForeignKeySource
.
objects
.
all
()
serializer
=
ForeignKeySourceSerializer
(
queryset
,
many
=
True
,
context
=
{
'request'
:
request
})
expected
=
[
{
'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/3/'
,
'name'
:
'source-3'
,
'target'
:
'http://testserver/foreignkeytarget/1/'
},
{
'url'
:
'http://testserver/foreignkeysource/4/'
,
'name'
:
'source-4'
,
'target'
:
'http://testserver/foreignkeytarget/2/'
},
]
self
.
assertEqual
(
serializer
.
data
,
expected
)
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/'
]}
serializer
=
ForeignKeyTargetSerializer
(
data
=
data
,
context
=
{
'request'
:
request
})
self
.
assertTrue
(
serializer
.
is_valid
())
obj
=
serializer
.
save
()
self
.
assertEqual
(
serializer
.
data
,
data
)
self
.
assertEqual
(
obj
.
name
,
'target-3'
)
# Ensure target 4 is added, and everything else is as expected
queryset
=
ForeignKeyTarget
.
objects
.
all
()
serializer
=
ForeignKeyTargetSerializer
(
queryset
,
many
=
True
,
context
=
{
'request'
:
request
})
expected
=
[
{
'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/3/'
,
'name'
:
'target-3'
,
'sources'
:
[
'http://testserver/foreignkeysource/1/'
,
'http://testserver/foreignkeysource/3/'
]},
]
self
.
assertEqual
(
serializer
.
data
,
expected
)
def
test_foreign_key_update_with_invalid_null
(
self
):
data
=
{
'url'
:
'http://testserver/foreignkeysource/1/'
,
'name'
:
'source-1'
,
'target'
:
None
}
instance
=
ForeignKeySource
.
objects
.
get
(
pk
=
1
)
serializer
=
ForeignKeySourceSerializer
(
instance
,
data
=
data
,
context
=
{
'request'
:
request
})
self
.
assertFalse
(
serializer
.
is_valid
())
self
.
assertEqual
(
serializer
.
errors
,
{
'target'
:
[
'This field may not be null.'
]})
class
HyperlinkedNullableForeignKeyTests
(
TestCase
):
urls
=
'tests.test_relations_hyperlink'
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
,
context
=
{
'request'
:
request
})
expected
=
[
{
'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/3/'
,
'name'
:
'source-3'
,
'target'
:
None
},
]
self
.
assertEqual
(
serializer
.
data
,
expected
)
def
test_foreign_key_create_with_valid_null
(
self
):
data
=
{
'url'
:
'http://testserver/nullableforeignkeysource/4/'
,
'name'
:
'source-4'
,
'target'
:
None
}
serializer
=
NullableForeignKeySourceSerializer
(
data
=
data
,
context
=
{
'request'
:
request
})
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
,
context
=
{
'request'
:
request
})
expected
=
[
{
'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/3/'
,
'name'
:
'source-3'
,
'target'
:
None
},
{
'url'
:
'http://testserver/nullableforeignkeysource/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
=
{
'url'
:
'http://testserver/nullableforeignkeysource/4/'
,
'name'
:
'source-4'
,
'target'
:
''
}
expected_data
=
{
'url'
:
'http://testserver/nullableforeignkeysource/4/'
,
'name'
:
'source-4'
,
'target'
:
None
}
serializer
=
NullableForeignKeySourceSerializer
(
data
=
data
,
context
=
{
'request'
:
request
})
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
,
context
=
{
'request'
:
request
})
expected
=
[
{
'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/3/'
,
'name'
:
'source-3'
,
'target'
:
None
},
{
'url'
:
'http://testserver/nullableforeignkeysource/4/'
,
'name'
:
'source-4'
,
'target'
:
None
}
]
self
.
assertEqual
(
serializer
.
data
,
expected
)
def
test_foreign_key_update_with_valid_null
(
self
):
data
=
{
'url'
:
'http://testserver/nullableforeignkeysource/1/'
,
'name'
:
'source-1'
,
'target'
:
None
}
instance
=
NullableForeignKeySource
.
objects
.
get
(
pk
=
1
)
serializer
=
NullableForeignKeySourceSerializer
(
instance
,
data
=
data
,
context
=
{
'request'
:
request
})
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
,
context
=
{
'request'
:
request
})
expected
=
[
{
'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/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
=
{
'url'
:
'http://testserver/nullableforeignkeysource/1/'
,
'name'
:
'source-1'
,
'target'
:
''
}
expected_data
=
{
'url'
:
'http://testserver/nullableforeignkeysource/1/'
,
'name'
:
'source-1'
,
'target'
:
None
}
instance
=
NullableForeignKeySource
.
objects
.
get
(
pk
=
1
)
serializer
=
NullableForeignKeySourceSerializer
(
instance
,
data
=
data
,
context
=
{
'request'
:
request
})
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
,
context
=
{
'request'
:
request
})
expected
=
[
{
'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/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 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)
# 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)
# print serializer.is_valid()
# print serializer.errors
# 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
# 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
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)
...
...
tests/test_relations_pk.py
View file @
093febb9
# from __future__ import unicode_literals
# from django.db import models
# from django.test import TestCase
# from django.utils import six
# from rest_framework import serializers
# from tests.models import (
# BlogPost, ManyToManyTarget, ManyToManySource, ForeignKeyTarget, ForeignKeySource,
# NullableForeignKeySource, OneToOneTarget, NullableOneToOneSource,
# )
# # ManyToMany
# class ManyToManyTargetSerializer(serializers.ModelSerializer):
# class Meta:
# model = ManyToManyTarget
# fields = ('id', 'name', 'sources')
# class ManyToManySourceSerializer(serializers.ModelSerializer):
# class Meta:
# model = ManyToManySource
# fields = ('id', 'name', 'targets')
# # ForeignKey
# class ForeignKeyTargetSerializer(serializers.ModelSerializer):
# class Meta:
# model = ForeignKeyTarget
# fields = ('id', 'name', 'sources')
# class ForeignKeySourceSerializer(serializers.ModelSerializer):
# class Meta:
# model = ForeignKeySource
# fields = ('id', 'name', 'target')
# # Nullable ForeignKey
# class NullableForeignKeySourceSerializer(serializers.ModelSerializer):
# class Meta:
# model = NullableForeignKeySource
# fields = ('id', 'name', 'target')
# # Nullable OneToOne
# class NullableOneToOneTargetSerializer(serializers.ModelSerializer):
# class Meta:
# model = OneToOneTarget
# fields = ('id', 'name', 'nullable_source')
# # TODO: Add test that .data cannot be accessed prior to .is_valid
# class PKManyToManyTests(TestCase):
# def setUp(self):
# for idx in range(1, 4):
# target = ManyToManyTarget(name='target-%d' % idx)
# target.save()
# source = ManyToManySource(name='source-%d' % idx)
# source.save()
# for target in ManyToManyTarget.objects.all():
# source.targets.add(target)
# def test_many_to_many_retrieve(self):
# queryset = ManyToManySource.objects.all()
# serializer = ManyToManySourceSerializer(queryset, many=True)
# expected = [
# {'id': 1, 'name': 'source-1', 'targets': [1]},
# {'id': 2, 'name': 'source-2', 'targets': [1, 2]},
# {'id': 3, 'name': 'source-3', 'targets': [1, 2, 3]}
# ]
# self.assertEqual(serializer.data, expected)
# def test_reverse_many_to_many_retrieve(self):
# queryset = ManyToManyTarget.objects.all()
# serializer = ManyToManyTargetSerializer(queryset, many=True)
# expected = [
# {'id': 1, 'name': 'target-1', 'sources': [1, 2, 3]},
# {'id': 2, 'name': 'target-2', 'sources': [2, 3]},
# {'id': 3, 'name': 'target-3', 'sources': [3]}
# ]
# self.assertEqual(serializer.data, expected)
# def test_many_to_many_update(self):
# data = {'id': 1, 'name': 'source-1', 'targets': [1, 2, 3]}
# instance = ManyToManySource.objects.get(pk=1)
# serializer = ManyToManySourceSerializer(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 = ManyToManySource.objects.all()
# serializer = ManyToManySourceSerializer(queryset, many=True)
# expected = [
# {'id': 1, 'name': 'source-1', 'targets': [1, 2, 3]},
# {'id': 2, 'name': 'source-2', 'targets': [1, 2]},
# {'id': 3, 'name': 'source-3', 'targets': [1, 2, 3]}
# ]
# self.assertEqual(serializer.data, expected)
# def test_reverse_many_to_many_update(self):
# data = {'id': 1, 'name': 'target-1', 'sources': [1]}
# instance = ManyToManyTarget.objects.get(pk=1)
# serializer = ManyToManyTargetSerializer(instance, data=data)
# self.assertTrue(serializer.is_valid())
# serializer.save()
# self.assertEqual(serializer.data, data)
# # Ensure target 1 is updated, and everything else is as expected
# queryset = ManyToManyTarget.objects.all()
# serializer = ManyToManyTargetSerializer(queryset, many=True)
# expected = [
# {'id': 1, 'name': 'target-1', 'sources': [1]},
# {'id': 2, 'name': 'target-2', 'sources': [2, 3]},
# {'id': 3, 'name': 'target-3', 'sources': [3]}
# ]
# self.assertEqual(serializer.data, expected)
# def test_many_to_many_create(self):
# data = {'id': 4, 'name': 'source-4', 'targets': [1, 3]}
# serializer = ManyToManySourceSerializer(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 = ManyToManySource.objects.all()
# serializer = ManyToManySourceSerializer(queryset, many=True)
# self.assertFalse(serializer.fields['targets'].read_only)
# expected = [
# {'id': 1, 'name': 'source-1', 'targets': [1]},
# {'id': 2, 'name': 'source-2', 'targets': [1, 2]},
# {'id': 3, 'name': 'source-3', 'targets': [1, 2, 3]},
# {'id': 4, 'name': 'source-4', 'targets': [1, 3]},
# ]
# self.assertEqual(serializer.data, expected)
# def test_reverse_many_to_many_create(self):
# data = {'id': 4, 'name': 'target-4', 'sources': [1, 3]}
# serializer = ManyToManyTargetSerializer(data=data)
# self.assertFalse(serializer.fields['sources'].read_only)
# self.assertTrue(serializer.is_valid())
# obj = serializer.save()
# self.assertEqual(serializer.data, data)
# self.assertEqual(obj.name, 'target-4')
# # Ensure target 4 is added, and everything else is as expected
# queryset = ManyToManyTarget.objects.all()
# serializer = ManyToManyTargetSerializer(queryset, many=True)
# expected = [
# {'id': 1, 'name': 'target-1', 'sources': [1, 2, 3]},
# {'id': 2, 'name': 'target-2', 'sources': [2, 3]},
# {'id': 3, 'name': 'target-3', 'sources': [3]},
# {'id': 4, 'name': 'target-4', 'sources': [1, 3]}
# ]
# self.assertEqual(serializer.data, expected)
# class PKForeignKeyTests(TestCase):
# def setUp(self):
# target = ForeignKeyTarget(name='target-1')
# target.save()
# new_target = ForeignKeyTarget(name='target-2')
# new_target.save()
# for idx in range(1, 4):
# source = ForeignKeySource(name='source-%d' % idx, target=target)
# source.save()
# def test_foreign_key_retrieve(self):
# 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}
# ]
# self.assertEqual(serializer.data, expected)
# def test_reverse_foreign_key_retrieve(self):
# queryset = ForeignKeyTarget.objects.all()
# serializer = ForeignKeyTargetSerializer(queryset, many=True)
# expected = [
# {'id': 1, 'name': 'target-1', 'sources': [1, 2, 3]},
# {'id': 2, 'name': 'target-2', 'sources': []},
# ]
# self.assertEqual(serializer.data, expected)
# def test_foreign_key_update(self):
# data = {'id': 1, 'name': 'source-1', 'target': 2}
# instance = ForeignKeySource.objects.get(pk=1)
# serializer = ForeignKeySourceSerializer(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 = ForeignKeySource.objects.all()
# serializer = ForeignKeySourceSerializer(queryset, many=True)
# expected = [
# {'id': 1, 'name': 'source-1', 'target': 2},
# {'id': 2, 'name': 'source-2', 'target': 1},
# {'id': 3, 'name': 'source-3', 'target': 1}
# ]
# self.assertEqual(serializer.data, expected)
# def test_foreign_key_update_incorrect_type(self):
# data = {'id': 1, 'name': 'source-1', 'target': 'foo'}
# instance = ForeignKeySource.objects.get(pk=1)
# serializer = ForeignKeySourceSerializer(instance, data=data)
# self.assertFalse(serializer.is_valid())
# 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 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)
# # 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
from
__future__
import
unicode_literals
from
django.test
import
TestCase
from
django.utils
import
six
from
rest_framework
import
serializers
from
tests.models
import
(
ManyToManyTarget
,
ManyToManySource
,
ForeignKeyTarget
,
ForeignKeySource
,
NullableForeignKeySource
,
OneToOneTarget
,
NullableOneToOneSource
,
)
# ManyToMany
class
ManyToManyTargetSerializer
(
serializers
.
ModelSerializer
):
class
Meta
:
model
=
ManyToManyTarget
fields
=
(
'id'
,
'name'
,
'sources'
)
class
ManyToManySourceSerializer
(
serializers
.
ModelSerializer
):
class
Meta
:
model
=
ManyToManySource
fields
=
(
'id'
,
'name'
,
'targets'
)
# ForeignKey
class
ForeignKeyTargetSerializer
(
serializers
.
ModelSerializer
):
class
Meta
:
model
=
ForeignKeyTarget
fields
=
(
'id'
,
'name'
,
'sources'
)
class
ForeignKeySourceSerializer
(
serializers
.
ModelSerializer
):
class
Meta
:
model
=
ForeignKeySource
fields
=
(
'id'
,
'name'
,
'target'
)
# Nullable ForeignKey
class
NullableForeignKeySourceSerializer
(
serializers
.
ModelSerializer
):
class
Meta
:
model
=
NullableForeignKeySource
fields
=
(
'id'
,
'name'
,
'target'
)
# Nullable OneToOne
class
NullableOneToOneTargetSerializer
(
serializers
.
ModelSerializer
):
class
Meta
:
model
=
OneToOneTarget
fields
=
(
'id'
,
'name'
,
'nullable_source'
)
# TODO: Add test that .data cannot be accessed prior to .is_valid
class
PKManyToManyTests
(
TestCase
):
def
setUp
(
self
):
for
idx
in
range
(
1
,
4
):
target
=
ManyToManyTarget
(
name
=
'target-
%
d'
%
idx
)
target
.
save
()
source
=
ManyToManySource
(
name
=
'source-
%
d'
%
idx
)
source
.
save
()
for
target
in
ManyToManyTarget
.
objects
.
all
():
source
.
targets
.
add
(
target
)
def
test_many_to_many_retrieve
(
self
):
queryset
=
ManyToManySource
.
objects
.
all
()
serializer
=
ManyToManySourceSerializer
(
queryset
,
many
=
True
)
expected
=
[
{
'id'
:
1
,
'name'
:
'source-1'
,
'targets'
:
[
1
]},
{
'id'
:
2
,
'name'
:
'source-2'
,
'targets'
:
[
1
,
2
]},
{
'id'
:
3
,
'name'
:
'source-3'
,
'targets'
:
[
1
,
2
,
3
]}
]
self
.
assertEqual
(
serializer
.
data
,
expected
)
def
test_reverse_many_to_many_retrieve
(
self
):
queryset
=
ManyToManyTarget
.
objects
.
all
()
serializer
=
ManyToManyTargetSerializer
(
queryset
,
many
=
True
)
expected
=
[
{
'id'
:
1
,
'name'
:
'target-1'
,
'sources'
:
[
1
,
2
,
3
]},
{
'id'
:
2
,
'name'
:
'target-2'
,
'sources'
:
[
2
,
3
]},
{
'id'
:
3
,
'name'
:
'target-3'
,
'sources'
:
[
3
]}
]
self
.
assertEqual
(
serializer
.
data
,
expected
)
def
test_many_to_many_update
(
self
):
data
=
{
'id'
:
1
,
'name'
:
'source-1'
,
'targets'
:
[
1
,
2
,
3
]}
instance
=
ManyToManySource
.
objects
.
get
(
pk
=
1
)
serializer
=
ManyToManySourceSerializer
(
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
=
ManyToManySource
.
objects
.
all
()
serializer
=
ManyToManySourceSerializer
(
queryset
,
many
=
True
)
expected
=
[
{
'id'
:
1
,
'name'
:
'source-1'
,
'targets'
:
[
1
,
2
,
3
]},
{
'id'
:
2
,
'name'
:
'source-2'
,
'targets'
:
[
1
,
2
]},
{
'id'
:
3
,
'name'
:
'source-3'
,
'targets'
:
[
1
,
2
,
3
]}
]
self
.
assertEqual
(
serializer
.
data
,
expected
)
def
test_reverse_many_to_many_update
(
self
):
data
=
{
'id'
:
1
,
'name'
:
'target-1'
,
'sources'
:
[
1
]}
instance
=
ManyToManyTarget
.
objects
.
get
(
pk
=
1
)
serializer
=
ManyToManyTargetSerializer
(
instance
,
data
=
data
)
self
.
assertTrue
(
serializer
.
is_valid
())
serializer
.
save
()
self
.
assertEqual
(
serializer
.
data
,
data
)
# Ensure target 1 is updated, and everything else is as expected
queryset
=
ManyToManyTarget
.
objects
.
all
()
serializer
=
ManyToManyTargetSerializer
(
queryset
,
many
=
True
)
expected
=
[
{
'id'
:
1
,
'name'
:
'target-1'
,
'sources'
:
[
1
]},
{
'id'
:
2
,
'name'
:
'target-2'
,
'sources'
:
[
2
,
3
]},
{
'id'
:
3
,
'name'
:
'target-3'
,
'sources'
:
[
3
]}
]
self
.
assertEqual
(
serializer
.
data
,
expected
)
def
test_many_to_many_create
(
self
):
data
=
{
'id'
:
4
,
'name'
:
'source-4'
,
'targets'
:
[
1
,
3
]}
serializer
=
ManyToManySourceSerializer
(
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
=
ManyToManySource
.
objects
.
all
()
serializer
=
ManyToManySourceSerializer
(
queryset
,
many
=
True
)
expected
=
[
{
'id'
:
1
,
'name'
:
'source-1'
,
'targets'
:
[
1
]},
{
'id'
:
2
,
'name'
:
'source-2'
,
'targets'
:
[
1
,
2
]},
{
'id'
:
3
,
'name'
:
'source-3'
,
'targets'
:
[
1
,
2
,
3
]},
{
'id'
:
4
,
'name'
:
'source-4'
,
'targets'
:
[
1
,
3
]},
]
self
.
assertEqual
(
serializer
.
data
,
expected
)
def
test_reverse_many_to_many_create
(
self
):
data
=
{
'id'
:
4
,
'name'
:
'target-4'
,
'sources'
:
[
1
,
3
]}
serializer
=
ManyToManyTargetSerializer
(
data
=
data
)
self
.
assertTrue
(
serializer
.
is_valid
())
obj
=
serializer
.
save
()
self
.
assertEqual
(
serializer
.
data
,
data
)
self
.
assertEqual
(
obj
.
name
,
'target-4'
)
# Ensure target 4 is added, and everything else is as expected
queryset
=
ManyToManyTarget
.
objects
.
all
()
serializer
=
ManyToManyTargetSerializer
(
queryset
,
many
=
True
)
expected
=
[
{
'id'
:
1
,
'name'
:
'target-1'
,
'sources'
:
[
1
,
2
,
3
]},
{
'id'
:
2
,
'name'
:
'target-2'
,
'sources'
:
[
2
,
3
]},
{
'id'
:
3
,
'name'
:
'target-3'
,
'sources'
:
[
3
]},
{
'id'
:
4
,
'name'
:
'target-4'
,
'sources'
:
[
1
,
3
]}
]
self
.
assertEqual
(
serializer
.
data
,
expected
)
class
PKForeignKeyTests
(
TestCase
):
def
setUp
(
self
):
target
=
ForeignKeyTarget
(
name
=
'target-1'
)
target
.
save
()
new_target
=
ForeignKeyTarget
(
name
=
'target-2'
)
new_target
.
save
()
for
idx
in
range
(
1
,
4
):
source
=
ForeignKeySource
(
name
=
'source-
%
d'
%
idx
,
target
=
target
)
source
.
save
()
def
test_foreign_key_retrieve
(
self
):
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
}
]
self
.
assertEqual
(
serializer
.
data
,
expected
)
def
test_reverse_foreign_key_retrieve
(
self
):
queryset
=
ForeignKeyTarget
.
objects
.
all
()
serializer
=
ForeignKeyTargetSerializer
(
queryset
,
many
=
True
)
expected
=
[
{
'id'
:
1
,
'name'
:
'target-1'
,
'sources'
:
[
1
,
2
,
3
]},
{
'id'
:
2
,
'name'
:
'target-2'
,
'sources'
:
[]},
]
self
.
assertEqual
(
serializer
.
data
,
expected
)
def
test_foreign_key_update
(
self
):
data
=
{
'id'
:
1
,
'name'
:
'source-1'
,
'target'
:
2
}
instance
=
ForeignKeySource
.
objects
.
get
(
pk
=
1
)
serializer
=
ForeignKeySourceSerializer
(
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
=
ForeignKeySource
.
objects
.
all
()
serializer
=
ForeignKeySourceSerializer
(
queryset
,
many
=
True
)
expected
=
[
{
'id'
:
1
,
'name'
:
'source-1'
,
'target'
:
2
},
{
'id'
:
2
,
'name'
:
'source-2'
,
'target'
:
1
},
{
'id'
:
3
,
'name'
:
'source-3'
,
'target'
:
1
}
]
self
.
assertEqual
(
serializer
.
data
,
expected
)
def
test_foreign_key_update_incorrect_type
(
self
):
data
=
{
'id'
:
1
,
'name'
:
'source-1'
,
'target'
:
'foo'
}
instance
=
ForeignKeySource
.
objects
.
get
(
pk
=
1
)
serializer
=
ForeignKeySourceSerializer
(
instance
,
data
=
data
)
self
.
assertFalse
(
serializer
.
is_valid
())
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):
# 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
)
# 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):
...
...
@@ -481,7 +478,6 @@
# def test_many_to_many_create(self):
# data = {'id': 2, 'name': 'source-2', 'targets': [self.target.pk]}
# serializer = ManyToManyThroughSourceSerializer(data=data)
# self.assertTrue(serializer.fields['targets'].read_only)
# self.assertTrue(serializer.is_valid())
# obj = serializer.save()
# self.assertEqual(obj.name, 'source-2')
...
...
@@ -490,9 +486,7 @@
# def test_many_to_many_reverse_create(self):
# data = {'id': 2, 'name': 'target-2', 'sources': [self.source.pk]}
# serializer = ManyToManyThroughTargetSerializer(data=data)
# self.assertTrue(serializer.fields['sources'].read_only)
# self.assertTrue(serializer.is_valid())
# serializer.save()
# obj = serializer.save()
# self.assertEqual(obj.name, 'target-2')
# self.assertEqual(obj.sources.count(), 0)
...
...
tests/test_relations_slug.py
View file @
093febb9
# from django.test import TestCase
# from rest_framework import serializers
# from tests.models import NullableForeignKeySource, ForeignKeySource, ForeignKeyTarget
# class ForeignKeyTargetSerializer(serializers.ModelSerializer):
# sources = serializers.SlugRelatedField(many=True, slug_field='name')
# class Meta:
# model = ForeignKeyTarget
# class ForeignKeySourceSerializer(serializers.ModelSerializer):
# target = serializers.SlugRelatedField(slug_field='name')
# class Meta:
# model = ForeignKeySource
# class NullableForeignKeySourceSerializer(serializers.ModelSerializer):
# target = serializers.SlugRelatedField(slug_field='name', required=False)
# class Meta:
# model = NullableForeignKeySource
# # TODO: M2M Tests, FKTests (Non-nullable), One2One
# class SlugForeignKeyTests(TestCase):
# def setUp(self):
# target = ForeignKeyTarget(name='target-1')
# target.save()
# new_target = ForeignKeyTarget(name='target-2')
# new_target.save()
# for idx in range(1, 4):
# source = ForeignKeySource(name='source-%d' % idx, target=target)
# source.save()
# def test_foreign_key_retrieve(self):
# queryset = ForeignKeySource.objects.all()
# serializer = ForeignKeySourceSerializer(queryset, many=True)
# expected = [
# {'id': 1, 'name': 'source-1', 'target': 'target-1'},
# {'id': 2, 'name': 'source-2', 'target': 'target-1'},
# {'id': 3, 'name': 'source-3', 'target': 'target-1'}
# ]
# self.assertEqual(serializer.data, expected)
# def test_reverse_foreign_key_retrieve(self):
# queryset = ForeignKeyTarget.objects.all()
# serializer = ForeignKeyTargetSerializer(queryset, many=True)
# expected = [
# {'id': 1, 'name': 'target-1', 'sources': ['source-1', 'source-2', 'source-3']},
# {'id': 2, 'name': 'target-2', 'sources': []},
# ]
# self.assertEqual(serializer.data, expected)
# def test_foreign_key_update(self):
# data = {'id': 1, 'name': 'source-1', 'target': 'target-2'}
# instance = ForeignKeySource.objects.get(pk=1)
# serializer = ForeignKeySourceSerializer(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 = ForeignKeySource.objects.all()
# serializer = ForeignKeySourceSerializer(queryset, many=True)
# expected = [
# {'id': 1, 'name': 'source-1', 'target': 'target-2'},
# {'id': 2, 'name': 'source-2', 'target': 'target-1'},
# {'id': 3, 'name': 'source-3', 'target': 'target-1'}
# ]
# self.assertEqual(serializer.data, expected)
# def test_foreign_key_update_incorrect_type(self):
# data = {'id': 1, 'name': 'source-1', 'target': 123}
# instance = ForeignKeySource.objects.get(pk=1)
# serializer = ForeignKeySourceSerializer(instance, data=data)
# self.assertFalse(serializer.is_valid())
# self.assertEqual(serializer.errors, {'target': ['Object with name=123 does not exist.']})
# def test_reverse_foreign_key_update(self):
# data = {'id': 2, 'name': 'target-2', 'sources': ['source-1', 'source-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': ['source-1', 'source-2', 'source-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': ['source-2']},
# {'id': 2, 'name': 'target-2', 'sources': ['source-1', 'source-3']},
# ]
# self.assertEqual(serializer.data, expected)
# def test_foreign_key_create(self):
# data = {'id': 4, 'name': 'source-4', 'target': 'target-2'}
# serializer = ForeignKeySourceSerializer(data=data)
# serializer.is_valid()
# 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': 'target-1'},
# {'id': 2, 'name': 'source-2', 'target': 'target-1'},
# {'id': 3, 'name': 'source-3', 'target': 'target-1'},
# {'id': 4, 'name': 'source-4', 'target': 'target-2'},
# ]
# self.assertEqual(serializer.data, expected)
# def test_reverse_foreign_key_create(self):
# data = {'id': 3, 'name': 'target-3', 'sources': ['source-1', 'source-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': ['source-2']},
# {'id': 2, 'name': 'target-2', 'sources': []},
# {'id': 3, 'name': 'target-3', 'sources': ['source-1', 'source-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.']})
# class SlugNullableForeignKeyTests(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': 'target-1'},
# {'id': 2, 'name': 'source-2', 'target': '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': 'target-1'},
# {'id': 2, 'name': 'source-2', 'target': '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': 'target-1'},
# {'id': 2, 'name': 'source-2', 'target': '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': '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': 'target-1'},
# {'id': 3, 'name': 'source-3', 'target': None}
# ]
# self.assertEqual(serializer.data, expected)
from
django.test
import
TestCase
from
rest_framework
import
serializers
from
tests.models
import
NullableForeignKeySource
,
ForeignKeySource
,
ForeignKeyTarget
class
ForeignKeyTargetSerializer
(
serializers
.
ModelSerializer
):
sources
=
serializers
.
SlugRelatedField
(
slug_field
=
'name'
,
queryset
=
ForeignKeySource
.
objects
.
all
(),
many
=
True
)
class
Meta
:
model
=
ForeignKeyTarget
class
ForeignKeySourceSerializer
(
serializers
.
ModelSerializer
):
target
=
serializers
.
SlugRelatedField
(
slug_field
=
'name'
,
queryset
=
ForeignKeyTarget
.
objects
.
all
()
)
class
Meta
:
model
=
ForeignKeySource
class
NullableForeignKeySourceSerializer
(
serializers
.
ModelSerializer
):
target
=
serializers
.
SlugRelatedField
(
slug_field
=
'name'
,
queryset
=
ForeignKeyTarget
.
objects
.
all
(),
allow_null
=
True
)
class
Meta
:
model
=
NullableForeignKeySource
# TODO: M2M Tests, FKTests (Non-nullable), One2One
class
SlugForeignKeyTests
(
TestCase
):
def
setUp
(
self
):
target
=
ForeignKeyTarget
(
name
=
'target-1'
)
target
.
save
()
new_target
=
ForeignKeyTarget
(
name
=
'target-2'
)
new_target
.
save
()
for
idx
in
range
(
1
,
4
):
source
=
ForeignKeySource
(
name
=
'source-
%
d'
%
idx
,
target
=
target
)
source
.
save
()
def
test_foreign_key_retrieve
(
self
):
queryset
=
ForeignKeySource
.
objects
.
all
()
serializer
=
ForeignKeySourceSerializer
(
queryset
,
many
=
True
)
expected
=
[
{
'id'
:
1
,
'name'
:
'source-1'
,
'target'
:
'target-1'
},
{
'id'
:
2
,
'name'
:
'source-2'
,
'target'
:
'target-1'
},
{
'id'
:
3
,
'name'
:
'source-3'
,
'target'
:
'target-1'
}
]
self
.
assertEqual
(
serializer
.
data
,
expected
)
def
test_reverse_foreign_key_retrieve
(
self
):
queryset
=
ForeignKeyTarget
.
objects
.
all
()
serializer
=
ForeignKeyTargetSerializer
(
queryset
,
many
=
True
)
expected
=
[
{
'id'
:
1
,
'name'
:
'target-1'
,
'sources'
:
[
'source-1'
,
'source-2'
,
'source-3'
]},
{
'id'
:
2
,
'name'
:
'target-2'
,
'sources'
:
[]},
]
self
.
assertEqual
(
serializer
.
data
,
expected
)
def
test_foreign_key_update
(
self
):
data
=
{
'id'
:
1
,
'name'
:
'source-1'
,
'target'
:
'target-2'
}
instance
=
ForeignKeySource
.
objects
.
get
(
pk
=
1
)
serializer
=
ForeignKeySourceSerializer
(
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
=
ForeignKeySource
.
objects
.
all
()
serializer
=
ForeignKeySourceSerializer
(
queryset
,
many
=
True
)
expected
=
[
{
'id'
:
1
,
'name'
:
'source-1'
,
'target'
:
'target-2'
},
{
'id'
:
2
,
'name'
:
'source-2'
,
'target'
:
'target-1'
},
{
'id'
:
3
,
'name'
:
'source-3'
,
'target'
:
'target-1'
}
]
self
.
assertEqual
(
serializer
.
data
,
expected
)
def
test_foreign_key_update_incorrect_type
(
self
):
data
=
{
'id'
:
1
,
'name'
:
'source-1'
,
'target'
:
123
}
instance
=
ForeignKeySource
.
objects
.
get
(
pk
=
1
)
serializer
=
ForeignKeySourceSerializer
(
instance
,
data
=
data
)
self
.
assertFalse
(
serializer
.
is_valid
())
self
.
assertEqual
(
serializer
.
errors
,
{
'target'
:
[
'Object with name=123 does not exist.'
]})
def
test_reverse_foreign_key_update
(
self
):
data
=
{
'id'
:
2
,
'name'
:
'target-2'
,
'sources'
:
[
'source-1'
,
'source-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'
:
[
'source-1'
,
'source-2'
,
'source-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'
:
[
'source-2'
]},
{
'id'
:
2
,
'name'
:
'target-2'
,
'sources'
:
[
'source-1'
,
'source-3'
]},
]
self
.
assertEqual
(
serializer
.
data
,
expected
)
def
test_foreign_key_create
(
self
):
data
=
{
'id'
:
4
,
'name'
:
'source-4'
,
'target'
:
'target-2'
}
serializer
=
ForeignKeySourceSerializer
(
data
=
data
)
serializer
.
is_valid
()
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'
:
'target-1'
},
{
'id'
:
2
,
'name'
:
'source-2'
,
'target'
:
'target-1'
},
{
'id'
:
3
,
'name'
:
'source-3'
,
'target'
:
'target-1'
},
{
'id'
:
4
,
'name'
:
'source-4'
,
'target'
:
'target-2'
},
]
self
.
assertEqual
(
serializer
.
data
,
expected
)
def
test_reverse_foreign_key_create
(
self
):
data
=
{
'id'
:
3
,
'name'
:
'target-3'
,
'sources'
:
[
'source-1'
,
'source-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'
:
[
'source-2'
]},
{
'id'
:
2
,
'name'
:
'target-2'
,
'sources'
:
[]},
{
'id'
:
3
,
'name'
:
'target-3'
,
'sources'
:
[
'source-1'
,
'source-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.'
]})
class
SlugNullableForeignKeyTests
(
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'
:
'target-1'
},
{
'id'
:
2
,
'name'
:
'source-2'
,
'target'
:
'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'
:
'target-1'
},
{
'id'
:
2
,
'name'
:
'source-2'
,
'target'
:
'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'
:
'target-1'
},
{
'id'
:
2
,
'name'
:
'source-2'
,
'target'
:
'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'
:
'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'
:
'target-1'
},
{
'id'
:
3
,
'name'
:
'source-3'
,
'target'
:
None
}
]
self
.
assertEqual
(
serializer
.
data
,
expected
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment