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
c1036c17
Commit
c1036c17
authored
Sep 03, 2014
by
Tom Christie
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
More test passing
parent
f2852811
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
734 additions
and
680 deletions
+734
-680
rest_framework/relations.py
+55
-1
tests/test_serializer.py
+0
-0
tests/test_serializer_bulk_update.py
+278
-278
tests/test_serializer_empty.py
+11
-11
tests/test_serializer_import.py
+16
-16
tests/test_serializer_nested.py
+349
-349
tests/test_serializers.py
+25
-25
No files found.
rest_framework/relations.py
View file @
c1036c17
from
rest_framework.fields
import
Field
from
rest_framework.reverse
import
reverse
from
django.core.exceptions
import
ObjectDoesNotExist
from
django.core.urlresolvers
import
resolve
,
get_script_prefix
from
django.core.urlresolvers
import
resolve
,
get_script_prefix
,
NoReverseMatch
from
rest_framework.compat
import
urlparse
...
...
@@ -100,11 +101,64 @@ class HyperlinkedIdentityField(RelatedField):
lookup_field
=
'pk'
def
__init__
(
self
,
**
kwargs
):
kwargs
[
'read_only'
]
=
True
self
.
view_name
=
kwargs
.
pop
(
'view_name'
)
self
.
lookup_field
=
kwargs
.
pop
(
'lookup_field'
,
self
.
lookup_field
)
self
.
lookup_url_kwarg
=
kwargs
.
pop
(
'lookup_url_kwarg'
,
self
.
lookup_field
)
super
(
HyperlinkedIdentityField
,
self
)
.
__init__
(
**
kwargs
)
def
get_attribute
(
self
,
instance
):
return
instance
def
to_primative
(
self
,
value
):
request
=
self
.
context
.
get
(
'request'
,
None
)
format
=
self
.
context
.
get
(
'format'
,
None
)
assert
request
is
not
None
,
(
"`HyperlinkedIdentityField` requires the request in the serializer"
" context. Add `context={'request': request}` when instantiating "
"the serializer."
)
# By default use whatever format is given for the current context
# unless the target is a different type to the source.
#
# Eg. Consider a HyperlinkedIdentityField pointing from a json
# representation to an html property of that representation...
#
# '/snippets/1/' should link to '/snippets/1/highlight/'
# ...but...
# '/snippets/1/.json' should link to '/snippets/1/highlight/.html'
if
format
and
self
.
format
and
self
.
format
!=
format
:
format
=
self
.
format
# Return the hyperlink, or error if incorrectly configured.
try
:
return
self
.
get_url
(
value
,
self
.
view_name
,
request
,
format
)
except
NoReverseMatch
:
msg
=
(
'Could not resolve URL for hyperlinked relationship using '
'view name "
%
s". You may have failed to include the related '
'model in your API, or incorrectly configured the '
'`lookup_field` attribute on this field.'
)
raise
Exception
(
msg
%
self
.
view_name
)
def
get_url
(
self
,
obj
,
view_name
,
request
,
format
):
"""
Given an object, return the URL that hyperlinks to the object.
May raise a `NoReverseMatch` if the `view_name` and `lookup_field`
attributes are not configured to correctly match the URL conf.
"""
# Unsaved objects will not yet have a valid URL.
if
obj
.
pk
is
None
:
return
None
lookup_value
=
getattr
(
obj
,
self
.
lookup_field
)
kwargs
=
{
self
.
lookup_url_kwarg
:
lookup_value
}
return
reverse
(
view_name
,
kwargs
=
kwargs
,
request
=
request
,
format
=
format
)
class
SlugRelatedField
(
RelatedField
):
def
__init__
(
self
,
**
kwargs
):
...
...
tests/test_serializer.py
View file @
c1036c17
This source diff could not be displayed because it is too large. You can
view the blob
instead.
tests/test_serializer_bulk_update.py
View file @
c1036c17
"""
Tests to cover bulk create and update using serializers.
"""
from
__future__
import
unicode_literals
from
django.test
import
TestCase
from
rest_framework
import
serializers
class
BulkCreateSerializerTests
(
TestCase
):
"""
Creating multiple instances using serializers.
"""
def
setUp
(
self
):
class
BookSerializer
(
serializers
.
Serializer
):
id
=
serializers
.
IntegerField
()
title
=
serializers
.
CharField
(
max_length
=
100
)
author
=
serializers
.
CharField
(
max_length
=
100
)
self
.
BookSerializer
=
BookSerializer
def
test_bulk_create_success
(
self
):
"""
Correct bulk update serialization should return the input data.
"""
data
=
[
{
'id'
:
0
,
'title'
:
'The electric kool-aid acid test'
,
'author'
:
'Tom Wolfe'
},
{
'id'
:
1
,
'title'
:
'If this is a man'
,
'author'
:
'Primo Levi'
},
{
'id'
:
2
,
'title'
:
'The wind-up bird chronicle'
,
'author'
:
'Haruki Murakami'
}
]
serializer
=
self
.
BookSerializer
(
data
=
data
,
many
=
True
)
self
.
assertEqual
(
serializer
.
is_valid
(),
True
)
self
.
assertEqual
(
serializer
.
object
,
data
)
def
test_bulk_create_errors
(
self
):
"""
Correct bulk update serialization should return the input data.
"""
data
=
[
{
'id'
:
0
,
'title'
:
'The electric kool-aid acid test'
,
'author'
:
'Tom Wolfe'
},
{
'id'
:
1
,
'title'
:
'If this is a man'
,
'author'
:
'Primo Levi'
},
{
'id'
:
'foo'
,
'title'
:
'The wind-up bird chronicle'
,
'author'
:
'Haruki Murakami'
}
]
expected_errors
=
[
{},
{},
{
'id'
:
[
'Enter a whole number.'
]}
]
serializer
=
self
.
BookSerializer
(
data
=
data
,
many
=
True
)
self
.
assertEqual
(
serializer
.
is_valid
(),
False
)
self
.
assertEqual
(
serializer
.
errors
,
expected_errors
)
def
test_invalid_list_datatype
(
self
):
"""
Data containing list of incorrect data type should return errors.
"""
data
=
[
'foo'
,
'bar'
,
'baz'
]
serializer
=
self
.
BookSerializer
(
data
=
data
,
many
=
True
)
self
.
assertEqual
(
serializer
.
is_valid
(),
False
)
expected_errors
=
[
{
'non_field_errors'
:
[
'Invalid data'
]},
{
'non_field_errors'
:
[
'Invalid data'
]},
{
'non_field_errors'
:
[
'Invalid data'
]}
]
self
.
assertEqual
(
serializer
.
errors
,
expected_errors
)
def
test_invalid_single_datatype
(
self
):
"""
Data containing a single incorrect data type should return errors.
"""
data
=
123
serializer
=
self
.
BookSerializer
(
data
=
data
,
many
=
True
)
self
.
assertEqual
(
serializer
.
is_valid
(),
False
)
expected_errors
=
{
'non_field_errors'
:
[
'Expected a list of items.'
]}
self
.
assertEqual
(
serializer
.
errors
,
expected_errors
)
def
test_invalid_single_object
(
self
):
"""
Data containing only a single object, instead of a list of objects
should return errors.
"""
data
=
{
'id'
:
0
,
'title'
:
'The electric kool-aid acid test'
,
'author'
:
'Tom Wolfe'
}
serializer
=
self
.
BookSerializer
(
data
=
data
,
many
=
True
)
self
.
assertEqual
(
serializer
.
is_valid
(),
False
)
expected_errors
=
{
'non_field_errors'
:
[
'Expected a list of items.'
]}
self
.
assertEqual
(
serializer
.
errors
,
expected_errors
)
class
BulkUpdateSerializerTests
(
TestCase
):
"""
Updating multiple instances using serializers.
"""
def
setUp
(
self
):
class
Book
(
object
):
"""
A data type that can be persisted to a mock storage backend
with `.save()` and `.delete()`.
"""
object_map
=
{}
def
__init__
(
self
,
id
,
title
,
author
):
self
.
id
=
id
self
.
title
=
title
self
.
author
=
author
def
save
(
self
):
Book
.
object_map
[
self
.
id
]
=
self
def
delete
(
self
):
del
Book
.
object_map
[
self
.
id
]
class
BookSerializer
(
serializers
.
Serializer
):
id
=
serializers
.
IntegerField
()
title
=
serializers
.
CharField
(
max_length
=
100
)
author
=
serializers
.
CharField
(
max_length
=
100
)
def
restore_object
(
self
,
attrs
,
instance
=
None
):
if
instance
:
instance
.
id
=
attrs
[
'id'
]
instance
.
title
=
attrs
[
'title'
]
instance
.
author
=
attrs
[
'author'
]
return
instance
return
Book
(
**
attrs
)
self
.
Book
=
Book
self
.
BookSerializer
=
BookSerializer
data
=
[
{
'id'
:
0
,
'title'
:
'The electric kool-aid acid test'
,
'author'
:
'Tom Wolfe'
},
{
'id'
:
1
,
'title'
:
'If this is a man'
,
'author'
:
'Primo Levi'
},
{
'id'
:
2
,
'title'
:
'The wind-up bird chronicle'
,
'author'
:
'Haruki Murakami'
}
]
for
item
in
data
:
book
=
Book
(
item
[
'id'
],
item
[
'title'
],
item
[
'author'
])
book
.
save
()
def
books
(
self
):
"""
Return all the objects in the mock storage backend.
"""
return
self
.
Book
.
object_map
.
values
()
def
test_bulk_update_success
(
self
):
"""
Correct bulk update serialization should return the input data.
"""
data
=
[
{
'id'
:
0
,
'title'
:
'The electric kool-aid acid test'
,
'author'
:
'Tom Wolfe'
},
{
'id'
:
2
,
'title'
:
'Kafka on the shore'
,
'author'
:
'Haruki Murakami'
}
]
serializer
=
self
.
BookSerializer
(
self
.
books
(),
data
=
data
,
many
=
True
,
allow_add_remove
=
True
)
self
.
assertEqual
(
serializer
.
is_valid
(),
True
)
self
.
assertEqual
(
serializer
.
data
,
data
)
serializer
.
save
()
new_data
=
self
.
BookSerializer
(
self
.
books
(),
many
=
True
)
.
data
self
.
assertEqual
(
data
,
new_data
)
def
test_bulk_update_and_create
(
self
):
"""
Bulk update serialization may also include created items.
"""
data
=
[
{
'id'
:
0
,
'title'
:
'The electric kool-aid acid test'
,
'author'
:
'Tom Wolfe'
},
{
'id'
:
3
,
'title'
:
'Kafka on the shore'
,
'author'
:
'Haruki Murakami'
}
]
serializer
=
self
.
BookSerializer
(
self
.
books
(),
data
=
data
,
many
=
True
,
allow_add_remove
=
True
)
self
.
assertEqual
(
serializer
.
is_valid
(),
True
)
self
.
assertEqual
(
serializer
.
data
,
data
)
serializer
.
save
()
new_data
=
self
.
BookSerializer
(
self
.
books
(),
many
=
True
)
.
data
self
.
assertEqual
(
data
,
new_data
)
def
test_bulk_update_invalid_create
(
self
):
"""
Bulk update serialization without allow_add_remove may not create items.
"""
data
=
[
{
'id'
:
0
,
'title'
:
'The electric kool-aid acid test'
,
'author'
:
'Tom Wolfe'
},
{
'id'
:
3
,
'title'
:
'Kafka on the shore'
,
'author'
:
'Haruki Murakami'
}
]
expected_errors
=
[
{},
{
'non_field_errors'
:
[
'Cannot create a new item, only existing items may be updated.'
]}
]
serializer
=
self
.
BookSerializer
(
self
.
books
(),
data
=
data
,
many
=
True
)
self
.
assertEqual
(
serializer
.
is_valid
(),
False
)
self
.
assertEqual
(
serializer
.
errors
,
expected_errors
)
def
test_bulk_update_error
(
self
):
"""
Incorrect bulk update serialization should return error data.
"""
data
=
[
{
'id'
:
0
,
'title'
:
'The electric kool-aid acid test'
,
'author'
:
'Tom Wolfe'
},
{
'id'
:
'foo'
,
'title'
:
'Kafka on the shore'
,
'author'
:
'Haruki Murakami'
}
]
expected_errors
=
[
{},
{
'id'
:
[
'Enter a whole number.'
]}
]
serializer
=
self
.
BookSerializer
(
self
.
books
(),
data
=
data
,
many
=
True
,
allow_add_remove
=
True
)
self
.
assertEqual
(
serializer
.
is_valid
(),
False
)
self
.
assertEqual
(
serializer
.
errors
,
expected_errors
)
#
"""
#
Tests to cover bulk create and update using serializers.
#
"""
#
from __future__ import unicode_literals
#
from django.test import TestCase
#
from rest_framework import serializers
#
class BulkCreateSerializerTests(TestCase):
#
"""
#
Creating multiple instances using serializers.
#
"""
#
def setUp(self):
#
class BookSerializer(serializers.Serializer):
#
id = serializers.IntegerField()
#
title = serializers.CharField(max_length=100)
#
author = serializers.CharField(max_length=100)
#
self.BookSerializer = BookSerializer
#
def test_bulk_create_success(self):
#
"""
#
Correct bulk update serialization should return the input data.
#
"""
#
data = [
#
{
#
'id': 0,
#
'title': 'The electric kool-aid acid test',
#
'author': 'Tom Wolfe'
#
}, {
#
'id': 1,
#
'title': 'If this is a man',
#
'author': 'Primo Levi'
#
}, {
#
'id': 2,
#
'title': 'The wind-up bird chronicle',
#
'author': 'Haruki Murakami'
#
}
#
]
#
serializer = self.BookSerializer(data=data, many=True)
#
self.assertEqual(serializer.is_valid(), True)
#
self.assertEqual(serializer.object, data)
#
def test_bulk_create_errors(self):
#
"""
#
Correct bulk update serialization should return the input data.
#
"""
#
data = [
#
{
#
'id': 0,
#
'title': 'The electric kool-aid acid test',
#
'author': 'Tom Wolfe'
#
}, {
#
'id': 1,
#
'title': 'If this is a man',
#
'author': 'Primo Levi'
#
}, {
#
'id': 'foo',
#
'title': 'The wind-up bird chronicle',
#
'author': 'Haruki Murakami'
#
}
#
]
#
expected_errors = [
#
{},
#
{},
#
{'id': ['Enter a whole number.']}
#
]
#
serializer = self.BookSerializer(data=data, many=True)
#
self.assertEqual(serializer.is_valid(), False)
#
self.assertEqual(serializer.errors, expected_errors)
#
def test_invalid_list_datatype(self):
#
"""
#
Data containing list of incorrect data type should return errors.
#
"""
#
data = ['foo', 'bar', 'baz']
#
serializer = self.BookSerializer(data=data, many=True)
#
self.assertEqual(serializer.is_valid(), False)
#
expected_errors = [
#
{'non_field_errors': ['Invalid data']},
#
{'non_field_errors': ['Invalid data']},
#
{'non_field_errors': ['Invalid data']}
#
]
#
self.assertEqual(serializer.errors, expected_errors)
#
def test_invalid_single_datatype(self):
#
"""
#
Data containing a single incorrect data type should return errors.
#
"""
#
data = 123
#
serializer = self.BookSerializer(data=data, many=True)
#
self.assertEqual(serializer.is_valid(), False)
#
expected_errors = {'non_field_errors': ['Expected a list of items.']}
#
self.assertEqual(serializer.errors, expected_errors)
#
def test_invalid_single_object(self):
#
"""
#
Data containing only a single object, instead of a list of objects
#
should return errors.
#
"""
#
data = {
#
'id': 0,
#
'title': 'The electric kool-aid acid test',
#
'author': 'Tom Wolfe'
#
}
#
serializer = self.BookSerializer(data=data, many=True)
#
self.assertEqual(serializer.is_valid(), False)
#
expected_errors = {'non_field_errors': ['Expected a list of items.']}
#
self.assertEqual(serializer.errors, expected_errors)
#
class BulkUpdateSerializerTests(TestCase):
#
"""
#
Updating multiple instances using serializers.
#
"""
#
def setUp(self):
#
class Book(object):
#
"""
#
A data type that can be persisted to a mock storage backend
#
with `.save()` and `.delete()`.
#
"""
#
object_map = {}
#
def __init__(self, id, title, author):
#
self.id = id
#
self.title = title
#
self.author = author
#
def save(self):
#
Book.object_map[self.id] = self
#
def delete(self):
#
del Book.object_map[self.id]
#
class BookSerializer(serializers.Serializer):
#
id = serializers.IntegerField()
#
title = serializers.CharField(max_length=100)
#
author = serializers.CharField(max_length=100)
#
def restore_object(self, attrs, instance=None):
#
if instance:
#
instance.id = attrs['id']
#
instance.title = attrs['title']
#
instance.author = attrs['author']
#
return instance
#
return Book(**attrs)
#
self.Book = Book
#
self.BookSerializer = BookSerializer
#
data = [
#
{
#
'id': 0,
#
'title': 'The electric kool-aid acid test',
#
'author': 'Tom Wolfe'
#
}, {
#
'id': 1,
#
'title': 'If this is a man',
#
'author': 'Primo Levi'
#
}, {
#
'id': 2,
#
'title': 'The wind-up bird chronicle',
#
'author': 'Haruki Murakami'
#
}
#
]
#
for item in data:
#
book = Book(item['id'], item['title'], item['author'])
#
book.save()
#
def books(self):
#
"""
#
Return all the objects in the mock storage backend.
#
"""
#
return self.Book.object_map.values()
#
def test_bulk_update_success(self):
#
"""
#
Correct bulk update serialization should return the input data.
#
"""
#
data = [
#
{
#
'id': 0,
#
'title': 'The electric kool-aid acid test',
#
'author': 'Tom Wolfe'
#
}, {
#
'id': 2,
#
'title': 'Kafka on the shore',
#
'author': 'Haruki Murakami'
#
}
#
]
#
serializer = self.BookSerializer(self.books(), data=data, many=True, allow_add_remove=True)
#
self.assertEqual(serializer.is_valid(), True)
#
self.assertEqual(serializer.data, data)
#
serializer.save()
#
new_data = self.BookSerializer(self.books(), many=True).data
#
self.assertEqual(data, new_data)
#
def test_bulk_update_and_create(self):
#
"""
#
Bulk update serialization may also include created items.
#
"""
#
data = [
#
{
#
'id': 0,
#
'title': 'The electric kool-aid acid test',
#
'author': 'Tom Wolfe'
#
}, {
#
'id': 3,
#
'title': 'Kafka on the shore',
#
'author': 'Haruki Murakami'
#
}
#
]
#
serializer = self.BookSerializer(self.books(), data=data, many=True, allow_add_remove=True)
#
self.assertEqual(serializer.is_valid(), True)
#
self.assertEqual(serializer.data, data)
#
serializer.save()
#
new_data = self.BookSerializer(self.books(), many=True).data
#
self.assertEqual(data, new_data)
#
def test_bulk_update_invalid_create(self):
#
"""
#
Bulk update serialization without allow_add_remove may not create items.
#
"""
#
data = [
#
{
#
'id': 0,
#
'title': 'The electric kool-aid acid test',
#
'author': 'Tom Wolfe'
#
}, {
#
'id': 3,
#
'title': 'Kafka on the shore',
#
'author': 'Haruki Murakami'
#
}
#
]
#
expected_errors = [
#
{},
#
{'non_field_errors': ['Cannot create a new item, only existing items may be updated.']}
#
]
#
serializer = self.BookSerializer(self.books(), data=data, many=True)
#
self.assertEqual(serializer.is_valid(), False)
#
self.assertEqual(serializer.errors, expected_errors)
#
def test_bulk_update_error(self):
#
"""
#
Incorrect bulk update serialization should return error data.
#
"""
#
data = [
#
{
#
'id': 0,
#
'title': 'The electric kool-aid acid test',
#
'author': 'Tom Wolfe'
#
}, {
#
'id': 'foo',
#
'title': 'Kafka on the shore',
#
'author': 'Haruki Murakami'
#
}
#
]
#
expected_errors = [
#
{},
#
{'id': ['Enter a whole number.']}
#
]
#
serializer = self.BookSerializer(self.books(), data=data, many=True, allow_add_remove=True)
#
self.assertEqual(serializer.is_valid(), False)
#
self.assertEqual(serializer.errors, expected_errors)
tests/test_serializer_empty.py
View file @
c1036c17
from
django.test
import
TestCase
from
rest_framework
import
serializers
#
from django.test import TestCase
#
from rest_framework import serializers
class
EmptySerializerTestCase
(
TestCase
):
def
test_empty_serializer
(
self
):
class
FooBarSerializer
(
serializers
.
Serializer
):
foo
=
serializers
.
IntegerField
()
bar
=
serializers
.
SerializerMethodField
(
'get_bar'
)
#
class EmptySerializerTestCase(TestCase):
#
def test_empty_serializer(self):
#
class FooBarSerializer(serializers.Serializer):
#
foo = serializers.IntegerField()
#
bar = serializers.SerializerMethodField('get_bar')
def
get_bar
(
self
,
obj
):
return
'bar'
#
def get_bar(self, obj):
#
return 'bar'
serializer
=
FooBarSerializer
()
self
.
assertEquals
(
serializer
.
data
,
{
'foo'
:
0
})
#
serializer = FooBarSerializer()
#
self.assertEquals(serializer.data, {'foo': 0})
tests/test_serializer_import.py
View file @
c1036c17
from
django.test
import
TestCase
#
from django.test import TestCase
from
rest_framework
import
serializers
from
tests.accounts.serializers
import
AccountSerializer
#
from rest_framework import serializers
#
from tests.accounts.serializers import AccountSerializer
class
ImportingModelSerializerTests
(
TestCase
):
"""
In some situations like, GH #1225, it is possible, especially in
testing, to import a serializer who's related models have not yet
been resolved by Django. `AccountSerializer` is an example of such
a serializer (imported at the top of this file).
"""
def
test_import_model_serializer
(
self
):
"""
The serializer at the top of this file should have been
imported successfully, and we should be able to instantiate it.
"""
self
.
assertIsInstance
(
AccountSerializer
(),
serializers
.
ModelSerializer
)
#
class ImportingModelSerializerTests(TestCase):
#
"""
#
In some situations like, GH #1225, it is possible, especially in
#
testing, to import a serializer who's related models have not yet
#
been resolved by Django. `AccountSerializer` is an example of such
#
a serializer (imported at the top of this file).
#
"""
#
def test_import_model_serializer(self):
#
"""
#
The serializer at the top of this file should have been
#
imported successfully, and we should be able to instantiate it.
#
"""
#
self.assertIsInstance(AccountSerializer(), serializers.ModelSerializer)
tests/test_serializer_nested.py
View file @
c1036c17
"""
Tests to cover nested serializers.
Doesn't cover model serializers.
"""
from
__future__
import
unicode_literals
from
django.test
import
TestCase
from
rest_framework
import
serializers
from
.
import
models
class
WritableNestedSerializerBasicTests
(
TestCase
):
"""
Tests for deserializing nested entities.
Basic tests that use serializers that simply restore to dicts.
"""
def
setUp
(
self
):
class
TrackSerializer
(
serializers
.
Serializer
):
order
=
serializers
.
IntegerField
()
title
=
serializers
.
CharField
(
max_length
=
100
)
duration
=
serializers
.
IntegerField
()
class
AlbumSerializer
(
serializers
.
Serializer
):
album_name
=
serializers
.
CharField
(
max_length
=
100
)
artist
=
serializers
.
CharField
(
max_length
=
100
)
tracks
=
TrackSerializer
(
many
=
True
)
self
.
AlbumSerializer
=
AlbumSerializer
def
test_nested_validation_success
(
self
):
"""
Correct nested serialization should return the input data.
"""
data
=
{
'album_name'
:
'Discovery'
,
'artist'
:
'Daft Punk'
,
'tracks'
:
[
{
'order'
:
1
,
'title'
:
'One More Time'
,
'duration'
:
235
},
{
'order'
:
2
,
'title'
:
'Aerodynamic'
,
'duration'
:
184
},
{
'order'
:
3
,
'title'
:
'Digital Love'
,
'duration'
:
239
}
]
}
serializer
=
self
.
AlbumSerializer
(
data
=
data
)
self
.
assertEqual
(
serializer
.
is_valid
(),
True
)
self
.
assertEqual
(
serializer
.
object
,
data
)
def
test_nested_validation_error
(
self
):
"""
Incorrect nested serialization should return appropriate error data.
"""
data
=
{
'album_name'
:
'Discovery'
,
'artist'
:
'Daft Punk'
,
'tracks'
:
[
{
'order'
:
1
,
'title'
:
'One More Time'
,
'duration'
:
235
},
{
'order'
:
2
,
'title'
:
'Aerodynamic'
,
'duration'
:
184
},
{
'order'
:
3
,
'title'
:
'Digital Love'
,
'duration'
:
'foobar'
}
]
}
expected_errors
=
{
'tracks'
:
[
{},
{},
{
'duration'
:
[
'Enter a whole number.'
]}
]
}
serializer
=
self
.
AlbumSerializer
(
data
=
data
)
self
.
assertEqual
(
serializer
.
is_valid
(),
False
)
self
.
assertEqual
(
serializer
.
errors
,
expected_errors
)
def
test_many_nested_validation_error
(
self
):
"""
Incorrect nested serialization should return appropriate error data
when multiple entities are being deserialized.
"""
data
=
[
{
'album_name'
:
'Russian Red'
,
'artist'
:
'I Love Your Glasses'
,
'tracks'
:
[
{
'order'
:
1
,
'title'
:
'Cigarettes'
,
'duration'
:
121
},
{
'order'
:
2
,
'title'
:
'No Past Land'
,
'duration'
:
198
},
{
'order'
:
3
,
'title'
:
'They Don
\'
t Believe'
,
'duration'
:
191
}
]
},
{
'album_name'
:
'Discovery'
,
'artist'
:
'Daft Punk'
,
'tracks'
:
[
{
'order'
:
1
,
'title'
:
'One More Time'
,
'duration'
:
235
},
{
'order'
:
2
,
'title'
:
'Aerodynamic'
,
'duration'
:
184
},
{
'order'
:
3
,
'title'
:
'Digital Love'
,
'duration'
:
'foobar'
}
]
}
]
expected_errors
=
[
{},
{
'tracks'
:
[
{},
{},
{
'duration'
:
[
'Enter a whole number.'
]}
]
}
]
serializer
=
self
.
AlbumSerializer
(
data
=
data
,
many
=
True
)
self
.
assertEqual
(
serializer
.
is_valid
(),
False
)
self
.
assertEqual
(
serializer
.
errors
,
expected_errors
)
class
WritableNestedSerializerObjectTests
(
TestCase
):
"""
Tests for deserializing nested entities.
These tests use serializers that restore to concrete objects.
"""
def
setUp
(
self
):
# Couple of concrete objects that we're going to deserialize into
class
Track
(
object
):
def
__init__
(
self
,
order
,
title
,
duration
):
self
.
order
,
self
.
title
,
self
.
duration
=
order
,
title
,
duration
def
__eq__
(
self
,
other
):
return
(
self
.
order
==
other
.
order
and
self
.
title
==
other
.
title
and
self
.
duration
==
other
.
duration
)
class
Album
(
object
):
def
__init__
(
self
,
album_name
,
artist
,
tracks
):
self
.
album_name
,
self
.
artist
,
self
.
tracks
=
album_name
,
artist
,
tracks
def
__eq__
(
self
,
other
):
return
(
self
.
album_name
==
other
.
album_name
and
self
.
artist
==
other
.
artist
and
self
.
tracks
==
other
.
tracks
)
# And their corresponding serializers
class
TrackSerializer
(
serializers
.
Serializer
):
order
=
serializers
.
IntegerField
()
title
=
serializers
.
CharField
(
max_length
=
100
)
duration
=
serializers
.
IntegerField
()
def
restore_object
(
self
,
attrs
,
instance
=
None
):
return
Track
(
attrs
[
'order'
],
attrs
[
'title'
],
attrs
[
'duration'
])
class
AlbumSerializer
(
serializers
.
Serializer
):
album_name
=
serializers
.
CharField
(
max_length
=
100
)
artist
=
serializers
.
CharField
(
max_length
=
100
)
tracks
=
TrackSerializer
(
many
=
True
)
def
restore_object
(
self
,
attrs
,
instance
=
None
):
return
Album
(
attrs
[
'album_name'
],
attrs
[
'artist'
],
attrs
[
'tracks'
])
self
.
Album
,
self
.
Track
=
Album
,
Track
self
.
AlbumSerializer
=
AlbumSerializer
def
test_nested_validation_success
(
self
):
"""
Correct nested serialization should return a restored object
that corresponds to the input data.
"""
data
=
{
'album_name'
:
'Discovery'
,
'artist'
:
'Daft Punk'
,
'tracks'
:
[
{
'order'
:
1
,
'title'
:
'One More Time'
,
'duration'
:
235
},
{
'order'
:
2
,
'title'
:
'Aerodynamic'
,
'duration'
:
184
},
{
'order'
:
3
,
'title'
:
'Digital Love'
,
'duration'
:
239
}
]
}
expected_object
=
self
.
Album
(
album_name
=
'Discovery'
,
artist
=
'Daft Punk'
,
tracks
=
[
self
.
Track
(
order
=
1
,
title
=
'One More Time'
,
duration
=
235
),
self
.
Track
(
order
=
2
,
title
=
'Aerodynamic'
,
duration
=
184
),
self
.
Track
(
order
=
3
,
title
=
'Digital Love'
,
duration
=
239
),
]
)
serializer
=
self
.
AlbumSerializer
(
data
=
data
)
self
.
assertEqual
(
serializer
.
is_valid
(),
True
)
self
.
assertEqual
(
serializer
.
object
,
expected_object
)
def
test_many_nested_validation_success
(
self
):
"""
Correct nested serialization should return multiple restored objects
that corresponds to the input data when multiple objects are
being deserialized.
"""
data
=
[
{
'album_name'
:
'Russian Red'
,
'artist'
:
'I Love Your Glasses'
,
'tracks'
:
[
{
'order'
:
1
,
'title'
:
'Cigarettes'
,
'duration'
:
121
},
{
'order'
:
2
,
'title'
:
'No Past Land'
,
'duration'
:
198
},
{
'order'
:
3
,
'title'
:
'They Don
\'
t Believe'
,
'duration'
:
191
}
]
},
{
'album_name'
:
'Discovery'
,
'artist'
:
'Daft Punk'
,
'tracks'
:
[
{
'order'
:
1
,
'title'
:
'One More Time'
,
'duration'
:
235
},
{
'order'
:
2
,
'title'
:
'Aerodynamic'
,
'duration'
:
184
},
{
'order'
:
3
,
'title'
:
'Digital Love'
,
'duration'
:
239
}
]
}
]
expected_object
=
[
self
.
Album
(
album_name
=
'Russian Red'
,
artist
=
'I Love Your Glasses'
,
tracks
=
[
self
.
Track
(
order
=
1
,
title
=
'Cigarettes'
,
duration
=
121
),
self
.
Track
(
order
=
2
,
title
=
'No Past Land'
,
duration
=
198
),
self
.
Track
(
order
=
3
,
title
=
'They Don
\'
t Believe'
,
duration
=
191
),
]
),
self
.
Album
(
album_name
=
'Discovery'
,
artist
=
'Daft Punk'
,
tracks
=
[
self
.
Track
(
order
=
1
,
title
=
'One More Time'
,
duration
=
235
),
self
.
Track
(
order
=
2
,
title
=
'Aerodynamic'
,
duration
=
184
),
self
.
Track
(
order
=
3
,
title
=
'Digital Love'
,
duration
=
239
),
]
)
]
serializer
=
self
.
AlbumSerializer
(
data
=
data
,
many
=
True
)
self
.
assertEqual
(
serializer
.
is_valid
(),
True
)
self
.
assertEqual
(
serializer
.
object
,
expected_object
)
class
ForeignKeyNestedSerializerUpdateTests
(
TestCase
):
def
setUp
(
self
):
class
Artist
(
object
):
def
__init__
(
self
,
name
):
self
.
name
=
name
def
__eq__
(
self
,
other
):
return
self
.
name
==
other
.
name
class
Album
(
object
):
def
__init__
(
self
,
name
,
artist
):
self
.
name
,
self
.
artist
=
name
,
artist
def
__eq__
(
self
,
other
):
return
self
.
name
==
other
.
name
and
self
.
artist
==
other
.
artist
class
ArtistSerializer
(
serializers
.
Serializer
):
name
=
serializers
.
CharField
()
def
restore_object
(
self
,
attrs
,
instance
=
None
):
if
instance
:
instance
.
name
=
attrs
[
'name'
]
else
:
instance
=
Artist
(
attrs
[
'name'
])
return
instance
class
AlbumSerializer
(
serializers
.
Serializer
):
name
=
serializers
.
CharField
()
by
=
ArtistSerializer
(
source
=
'artist'
)
def
restore_object
(
self
,
attrs
,
instance
=
None
):
if
instance
:
instance
.
name
=
attrs
[
'name'
]
instance
.
artist
=
attrs
[
'artist'
]
else
:
instance
=
Album
(
attrs
[
'name'
],
attrs
[
'artist'
])
return
instance
self
.
Artist
=
Artist
self
.
Album
=
Album
self
.
AlbumSerializer
=
AlbumSerializer
def
test_create_via_foreign_key_with_source
(
self
):
"""
Check that we can both *create* and *update* into objects across
ForeignKeys that have a `source` specified.
Regression test for #1170
"""
data
=
{
'name'
:
'Discovery'
,
'by'
:
{
'name'
:
'Daft Punk'
},
}
expected
=
self
.
Album
(
artist
=
self
.
Artist
(
'Daft Punk'
),
name
=
'Discovery'
)
# create
serializer
=
self
.
AlbumSerializer
(
data
=
data
)
self
.
assertEqual
(
serializer
.
is_valid
(),
True
)
self
.
assertEqual
(
serializer
.
object
,
expected
)
# update
original
=
self
.
Album
(
artist
=
self
.
Artist
(
'The Bats'
),
name
=
'Free All the Monsters'
)
serializer
=
self
.
AlbumSerializer
(
instance
=
original
,
data
=
data
)
self
.
assertEqual
(
serializer
.
is_valid
(),
True
)
self
.
assertEqual
(
serializer
.
object
,
expected
)
class
NestedModelSerializerUpdateTests
(
TestCase
):
def
test_second_nested_level
(
self
):
john
=
models
.
Person
.
objects
.
create
(
name
=
"john"
)
post
=
john
.
blogpost_set
.
create
(
title
=
"Test blog post"
)
post
.
blogpostcomment_set
.
create
(
text
=
"I hate this blog post"
)
post
.
blogpostcomment_set
.
create
(
text
=
"I love this blog post"
)
class
BlogPostCommentSerializer
(
serializers
.
ModelSerializer
):
class
Meta
:
model
=
models
.
BlogPostComment
class
BlogPostSerializer
(
serializers
.
ModelSerializer
):
comments
=
BlogPostCommentSerializer
(
many
=
True
,
source
=
'blogpostcomment_set'
)
class
Meta
:
model
=
models
.
BlogPost
fields
=
(
'id'
,
'title'
,
'comments'
)
class
PersonSerializer
(
serializers
.
ModelSerializer
):
posts
=
BlogPostSerializer
(
many
=
True
,
source
=
'blogpost_set'
)
class
Meta
:
model
=
models
.
Person
fields
=
(
'id'
,
'name'
,
'age'
,
'posts'
)
serialize
=
PersonSerializer
(
instance
=
john
)
deserialize
=
PersonSerializer
(
data
=
serialize
.
data
,
instance
=
john
)
self
.
assertTrue
(
deserialize
.
is_valid
())
result
=
deserialize
.
object
result
.
save
()
self
.
assertEqual
(
result
.
id
,
john
.
id
)
#
"""
#
Tests to cover nested serializers.
#
Doesn't cover model serializers.
#
"""
#
from __future__ import unicode_literals
#
from django.test import TestCase
#
from rest_framework import serializers
#
from . import models
#
class WritableNestedSerializerBasicTests(TestCase):
#
"""
#
Tests for deserializing nested entities.
#
Basic tests that use serializers that simply restore to dicts.
#
"""
#
def setUp(self):
#
class TrackSerializer(serializers.Serializer):
#
order = serializers.IntegerField()
#
title = serializers.CharField(max_length=100)
#
duration = serializers.IntegerField()
#
class AlbumSerializer(serializers.Serializer):
#
album_name = serializers.CharField(max_length=100)
#
artist = serializers.CharField(max_length=100)
#
tracks = TrackSerializer(many=True)
#
self.AlbumSerializer = AlbumSerializer
#
def test_nested_validation_success(self):
#
"""
#
Correct nested serialization should return the input data.
#
"""
#
data = {
#
'album_name': 'Discovery',
#
'artist': 'Daft Punk',
#
'tracks': [
#
{'order': 1, 'title': 'One More Time', 'duration': 235},
#
{'order': 2, 'title': 'Aerodynamic', 'duration': 184},
#
{'order': 3, 'title': 'Digital Love', 'duration': 239}
#
]
#
}
#
serializer = self.AlbumSerializer(data=data)
#
self.assertEqual(serializer.is_valid(), True)
#
self.assertEqual(serializer.object, data)
#
def test_nested_validation_error(self):
#
"""
#
Incorrect nested serialization should return appropriate error data.
#
"""
#
data = {
#
'album_name': 'Discovery',
#
'artist': 'Daft Punk',
#
'tracks': [
#
{'order': 1, 'title': 'One More Time', 'duration': 235},
#
{'order': 2, 'title': 'Aerodynamic', 'duration': 184},
#
{'order': 3, 'title': 'Digital Love', 'duration': 'foobar'}
#
]
#
}
#
expected_errors = {
#
'tracks': [
#
{},
#
{},
#
{'duration': ['Enter a whole number.']}
#
]
#
}
#
serializer = self.AlbumSerializer(data=data)
#
self.assertEqual(serializer.is_valid(), False)
#
self.assertEqual(serializer.errors, expected_errors)
#
def test_many_nested_validation_error(self):
#
"""
#
Incorrect nested serialization should return appropriate error data
#
when multiple entities are being deserialized.
#
"""
#
data = [
#
{
#
'album_name': 'Russian Red',
#
'artist': 'I Love Your Glasses',
#
'tracks': [
#
{'order': 1, 'title': 'Cigarettes', 'duration': 121},
#
{'order': 2, 'title': 'No Past Land', 'duration': 198},
#
{'order': 3, 'title': 'They Don\'t Believe', 'duration': 191}
#
]
#
},
#
{
#
'album_name': 'Discovery',
#
'artist': 'Daft Punk',
#
'tracks': [
#
{'order': 1, 'title': 'One More Time', 'duration': 235},
#
{'order': 2, 'title': 'Aerodynamic', 'duration': 184},
#
{'order': 3, 'title': 'Digital Love', 'duration': 'foobar'}
#
]
#
}
#
]
#
expected_errors = [
#
{},
#
{
#
'tracks': [
#
{},
#
{},
#
{'duration': ['Enter a whole number.']}
#
]
#
}
#
]
#
serializer = self.AlbumSerializer(data=data, many=True)
#
self.assertEqual(serializer.is_valid(), False)
#
self.assertEqual(serializer.errors, expected_errors)
#
class WritableNestedSerializerObjectTests(TestCase):
#
"""
#
Tests for deserializing nested entities.
#
These tests use serializers that restore to concrete objects.
#
"""
#
def setUp(self):
#
# Couple of concrete objects that we're going to deserialize into
#
class Track(object):
#
def __init__(self, order, title, duration):
#
self.order, self.title, self.duration = order, title, duration
#
def __eq__(self, other):
#
return (
#
self.order == other.order and
#
self.title == other.title and
#
self.duration == other.duration
#
)
#
class Album(object):
#
def __init__(self, album_name, artist, tracks):
#
self.album_name, self.artist, self.tracks = album_name, artist, tracks
#
def __eq__(self, other):
#
return (
#
self.album_name == other.album_name and
#
self.artist == other.artist and
#
self.tracks == other.tracks
#
)
#
# And their corresponding serializers
#
class TrackSerializer(serializers.Serializer):
#
order = serializers.IntegerField()
#
title = serializers.CharField(max_length=100)
#
duration = serializers.IntegerField()
#
def restore_object(self, attrs, instance=None):
#
return Track(attrs['order'], attrs['title'], attrs['duration'])
#
class AlbumSerializer(serializers.Serializer):
#
album_name = serializers.CharField(max_length=100)
#
artist = serializers.CharField(max_length=100)
#
tracks = TrackSerializer(many=True)
#
def restore_object(self, attrs, instance=None):
#
return Album(attrs['album_name'], attrs['artist'], attrs['tracks'])
#
self.Album, self.Track = Album, Track
#
self.AlbumSerializer = AlbumSerializer
#
def test_nested_validation_success(self):
#
"""
#
Correct nested serialization should return a restored object
#
that corresponds to the input data.
#
"""
#
data = {
#
'album_name': 'Discovery',
#
'artist': 'Daft Punk',
#
'tracks': [
#
{'order': 1, 'title': 'One More Time', 'duration': 235},
#
{'order': 2, 'title': 'Aerodynamic', 'duration': 184},
#
{'order': 3, 'title': 'Digital Love', 'duration': 239}
#
]
#
}
#
expected_object = self.Album(
#
album_name='Discovery',
#
artist='Daft Punk',
#
tracks=[
#
self.Track(order=1, title='One More Time', duration=235),
#
self.Track(order=2, title='Aerodynamic', duration=184),
#
self.Track(order=3, title='Digital Love', duration=239),
#
]
#
)
#
serializer = self.AlbumSerializer(data=data)
#
self.assertEqual(serializer.is_valid(), True)
#
self.assertEqual(serializer.object, expected_object)
#
def test_many_nested_validation_success(self):
#
"""
#
Correct nested serialization should return multiple restored objects
#
that corresponds to the input data when multiple objects are
#
being deserialized.
#
"""
#
data = [
#
{
#
'album_name': 'Russian Red',
#
'artist': 'I Love Your Glasses',
#
'tracks': [
#
{'order': 1, 'title': 'Cigarettes', 'duration': 121},
#
{'order': 2, 'title': 'No Past Land', 'duration': 198},
#
{'order': 3, 'title': 'They Don\'t Believe', 'duration': 191}
#
]
#
},
#
{
#
'album_name': 'Discovery',
#
'artist': 'Daft Punk',
#
'tracks': [
#
{'order': 1, 'title': 'One More Time', 'duration': 235},
#
{'order': 2, 'title': 'Aerodynamic', 'duration': 184},
#
{'order': 3, 'title': 'Digital Love', 'duration': 239}
#
]
#
}
#
]
#
expected_object = [
#
self.Album(
#
album_name='Russian Red',
#
artist='I Love Your Glasses',
#
tracks=[
#
self.Track(order=1, title='Cigarettes', duration=121),
#
self.Track(order=2, title='No Past Land', duration=198),
#
self.Track(order=3, title='They Don\'t Believe', duration=191),
#
]
#
),
#
self.Album(
#
album_name='Discovery',
#
artist='Daft Punk',
#
tracks=[
#
self.Track(order=1, title='One More Time', duration=235),
#
self.Track(order=2, title='Aerodynamic', duration=184),
#
self.Track(order=3, title='Digital Love', duration=239),
#
]
#
)
#
]
#
serializer = self.AlbumSerializer(data=data, many=True)
#
self.assertEqual(serializer.is_valid(), True)
#
self.assertEqual(serializer.object, expected_object)
#
class ForeignKeyNestedSerializerUpdateTests(TestCase):
#
def setUp(self):
#
class Artist(object):
#
def __init__(self, name):
#
self.name = name
#
def __eq__(self, other):
#
return self.name == other.name
#
class Album(object):
#
def __init__(self, name, artist):
#
self.name, self.artist = name, artist
#
def __eq__(self, other):
#
return self.name == other.name and self.artist == other.artist
#
class ArtistSerializer(serializers.Serializer):
#
name = serializers.CharField()
#
def restore_object(self, attrs, instance=None):
#
if instance:
#
instance.name = attrs['name']
#
else:
#
instance = Artist(attrs['name'])
#
return instance
#
class AlbumSerializer(serializers.Serializer):
#
name = serializers.CharField()
#
by = ArtistSerializer(source='artist')
#
def restore_object(self, attrs, instance=None):
#
if instance:
#
instance.name = attrs['name']
#
instance.artist = attrs['artist']
#
else:
#
instance = Album(attrs['name'], attrs['artist'])
#
return instance
#
self.Artist = Artist
#
self.Album = Album
#
self.AlbumSerializer = AlbumSerializer
#
def test_create_via_foreign_key_with_source(self):
#
"""
#
Check that we can both *create* and *update* into objects across
#
ForeignKeys that have a `source` specified.
#
Regression test for #1170
#
"""
#
data = {
#
'name': 'Discovery',
#
'by': {'name': 'Daft Punk'},
#
}
#
expected = self.Album(artist=self.Artist('Daft Punk'), name='Discovery')
#
# create
#
serializer = self.AlbumSerializer(data=data)
#
self.assertEqual(serializer.is_valid(), True)
#
self.assertEqual(serializer.object, expected)
#
# update
#
original = self.Album(artist=self.Artist('The Bats'), name='Free All the Monsters')
#
serializer = self.AlbumSerializer(instance=original, data=data)
#
self.assertEqual(serializer.is_valid(), True)
#
self.assertEqual(serializer.object, expected)
#
class NestedModelSerializerUpdateTests(TestCase):
#
def test_second_nested_level(self):
#
john = models.Person.objects.create(name="john")
#
post = john.blogpost_set.create(title="Test blog post")
#
post.blogpostcomment_set.create(text="I hate this blog post")
#
post.blogpostcomment_set.create(text="I love this blog post")
#
class BlogPostCommentSerializer(serializers.ModelSerializer):
#
class Meta:
#
model = models.BlogPostComment
#
class BlogPostSerializer(serializers.ModelSerializer):
#
comments = BlogPostCommentSerializer(many=True, source='blogpostcomment_set')
#
class Meta:
#
model = models.BlogPost
#
fields = ('id', 'title', 'comments')
#
class PersonSerializer(serializers.ModelSerializer):
#
posts = BlogPostSerializer(many=True, source='blogpost_set')
#
class Meta:
#
model = models.Person
#
fields = ('id', 'name', 'age', 'posts')
#
serialize = PersonSerializer(instance=john)
#
deserialize = PersonSerializer(data=serialize.data, instance=john)
#
self.assertTrue(deserialize.is_valid())
#
result = deserialize.object
#
result.save()
#
self.assertEqual(result.id, john.id)
tests/test_serializers.py
View file @
c1036c17
from
django.test
import
TestCase
from
django.utils
import
six
from
rest_framework.serializers
import
_resolve_model
from
tests.models
import
BasicModel
#
from django.test import TestCase
#
from django.utils import six
#
from rest_framework.serializers import _resolve_model
#
from tests.models import BasicModel
class
ResolveModelTests
(
TestCase
):
"""
`_resolve_model` should return a Django model class given the
provided argument is a Django model class itself, or a properly
formatted string representation of one.
"""
def
test_resolve_django_model
(
self
):
resolved_model
=
_resolve_model
(
BasicModel
)
self
.
assertEqual
(
resolved_model
,
BasicModel
)
#
class ResolveModelTests(TestCase):
#
"""
#
`_resolve_model` should return a Django model class given the
#
provided argument is a Django model class itself, or a properly
#
formatted string representation of one.
#
"""
#
def test_resolve_django_model(self):
#
resolved_model = _resolve_model(BasicModel)
#
self.assertEqual(resolved_model, BasicModel)
def
test_resolve_string_representation
(
self
):
resolved_model
=
_resolve_model
(
'tests.BasicModel'
)
self
.
assertEqual
(
resolved_model
,
BasicModel
)
#
def test_resolve_string_representation(self):
#
resolved_model = _resolve_model('tests.BasicModel')
#
self.assertEqual(resolved_model, BasicModel)
def
test_resolve_unicode_representation
(
self
):
resolved_model
=
_resolve_model
(
six
.
text_type
(
'tests.BasicModel'
))
self
.
assertEqual
(
resolved_model
,
BasicModel
)
#
def test_resolve_unicode_representation(self):
#
resolved_model = _resolve_model(six.text_type('tests.BasicModel'))
#
self.assertEqual(resolved_model, BasicModel)
def
test_resolve_non_django_model
(
self
):
with
self
.
assertRaises
(
ValueError
):
_resolve_model
(
TestCase
)
#
def test_resolve_non_django_model(self):
#
with self.assertRaises(ValueError):
#
_resolve_model(TestCase)
def
test_resolve_improper_string_representation
(
self
):
with
self
.
assertRaises
(
ValueError
):
_resolve_model
(
'BasicModel'
)
#
def test_resolve_improper_string_representation(self):
#
with self.assertRaises(ValueError):
#
_resolve_model('BasicModel')
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