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
a5178e9a
Commit
a5178e9a
authored
Dec 07, 2012
by
Tom Christie
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #451 from markotibold/#431
Call model's .full_clean() method, eg. to validate uniqueness
parents
a463ddbb
919aff32
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
54 additions
and
13 deletions
+54
-13
rest_framework/serializers.py
+32
-8
rest_framework/tests/models.py
+2
-2
rest_framework/tests/serializer.py
+20
-3
No files found.
rest_framework/serializers.py
View file @
a5178e9a
...
...
@@ -127,6 +127,17 @@ class BaseSerializer(Field):
"""
return
{}
def
get_excluded_fieldnames
(
self
):
"""
Returns the fieldnames that should not be validated.
"""
excluded_fields
=
list
(
self
.
opts
.
exclude
)
for
field
in
self
.
fields
.
keys
()
+
self
.
get_default_fields
()
.
keys
():
if
self
.
opts
.
fields
:
if
field
not
in
self
.
opts
.
fields
+
self
.
opts
.
exclude
:
excluded_fields
.
append
(
field
)
return
excluded_fields
def
get_fields
(
self
):
"""
Returns the complete set of fields for the object as a dict.
...
...
@@ -226,10 +237,17 @@ class BaseSerializer(Field):
except
ValidationError
as
err
:
self
.
_errors
[
field_name
]
=
self
.
_errors
.
get
(
field_name
,
[])
+
list
(
err
.
messages
)
try
:
attrs
=
self
.
validate
(
attrs
)
except
ValidationError
as
err
:
self
.
_errors
[
'non_field_errors'
]
=
err
.
messages
# We don't run .validate() because field-validation failed and thus `attrs` may not be complete.
# which in turn can cause inconsistent validation errors.
if
not
self
.
_errors
:
try
:
attrs
=
self
.
validate
(
attrs
)
except
ValidationError
as
err
:
if
hasattr
(
err
,
'message_dict'
):
for
field_name
,
error_messages
in
err
.
message_dict
.
items
():
self
.
_errors
[
field_name
]
=
self
.
_errors
.
get
(
field_name
,
[])
+
list
(
error_messages
)
elif
hasattr
(
err
,
'messages'
):
self
.
_errors
[
'non_field_errors'
]
=
err
.
messages
return
attrs
...
...
@@ -441,10 +459,6 @@ class ModelSerializer(Serializer):
kwargs
[
'choices'
]
=
model_field
.
flatchoices
return
ChoiceField
(
**
kwargs
)
max_length
=
getattr
(
model_field
,
'max_length'
,
None
)
if
max_length
:
kwargs
[
'max_length'
]
=
max_length
field_mapping
=
{
models
.
FloatField
:
FloatField
,
models
.
IntegerField
:
IntegerField
,
...
...
@@ -468,6 +482,16 @@ class ModelSerializer(Serializer):
except
KeyError
:
return
ModelField
(
model_field
=
model_field
,
**
kwargs
)
def
validate
(
self
,
attrs
):
copied_attrs
=
copy
.
deepcopy
(
attrs
)
restored_object
=
self
.
restore_object
(
copied_attrs
,
instance
=
getattr
(
self
,
'object'
,
None
))
self
.
perform_model_validation
(
restored_object
)
return
attrs
def
perform_model_validation
(
self
,
restored_object
):
# Call Django's full_clean() which in turn calls: Model.clean_fields(), Model.clean(), Model.validat_unique()
restored_object
.
full_clean
(
exclude
=
list
(
self
.
get_excluded_fieldnames
()))
def
restore_object
(
self
,
attrs
,
instance
=
None
):
"""
Restore the model instance.
...
...
rest_framework/tests/models.py
View file @
a5178e9a
...
...
@@ -61,7 +61,7 @@ class BasicModel(RESTFrameworkModel):
class
SlugBasedModel
(
RESTFrameworkModel
):
text
=
models
.
CharField
(
max_length
=
100
)
slug
=
models
.
SlugField
(
max_length
=
32
)
slug
=
models
.
SlugField
(
max_length
=
32
,
blank
=
True
)
class
DefaultValueModel
(
RESTFrameworkModel
):
...
...
@@ -160,7 +160,7 @@ class Photo(RESTFrameworkModel):
# Model for issue #324
class
BlankFieldModel
(
RESTFrameworkModel
):
title
=
models
.
CharField
(
max_length
=
100
,
blank
=
True
)
title
=
models
.
CharField
(
max_length
=
100
,
blank
=
True
,
null
=
True
)
# Model for issue #380
...
...
rest_framework/tests/serializer.py
View file @
a5178e9a
import
datetime
,
pickle
from
django.test
import
TestCase
from
rest_framework
import
serializers
from
rest_framework.tests.models
import
(
ActionItem
,
Anchor
,
BasicModel
,
from
rest_framework.tests.models
import
(
A
lbum
,
A
ctionItem
,
Anchor
,
BasicModel
,
BlankFieldModel
,
BlogPost
,
Book
,
CallableDefaultValueModel
,
DefaultValueModel
,
ManyToManyModel
,
Person
,
ReadOnlyManyToManyModel
)
...
...
@@ -48,7 +48,7 @@ class BookSerializer(serializers.ModelSerializer):
class
ActionItemSerializer
(
serializers
.
ModelSerializer
):
class
Meta
:
model
=
ActionItem
...
...
@@ -62,6 +62,12 @@ class PersonSerializer(serializers.ModelSerializer):
read_only_fields
=
(
'age'
,)
class
AlbumsSerializer
(
serializers
.
ModelSerializer
):
class
Meta
:
model
=
Album
class
BasicTests
(
TestCase
):
def
setUp
(
self
):
self
.
comment
=
Comment
(
...
...
@@ -169,7 +175,7 @@ class ValidationTests(TestCase):
'content'
:
'x'
*
1001
,
'created'
:
datetime
.
datetime
(
2012
,
1
,
1
)
}
self
.
actionitem
=
ActionItem
(
'Some to do item'
,
self
.
actionitem
=
ActionItem
(
title
=
'Some to do item'
,
)
def
test_create
(
self
):
...
...
@@ -276,6 +282,17 @@ class ValidationTests(TestCase):
self
.
assertEquals
(
serializer
.
is_valid
(),
False
)
self
.
assertEquals
(
serializer
.
errors
,
{
'info'
:
[
u'Ensure this value has at most 12 characters (it has 13).'
]})
def
test_validate_unique
(
self
):
"""
Just check if serializers.ModelSerializer.perform_model_validation() handles unique checks via .full_clean()
"""
serializer
=
AlbumsSerializer
(
data
=
{
'title'
:
'a'
})
serializer
.
is_valid
()
serializer
.
save
()
second_serializer
=
AlbumsSerializer
(
data
=
{
'title'
:
'a'
})
self
.
assertFalse
(
second_serializer
.
is_valid
())
self
.
assertEqual
(
second_serializer
.
errors
,
{
'title'
:
[
u'Album with this Title already exists.'
]})
class
RegexValidationTest
(
TestCase
):
def
test_create_failed
(
self
):
...
...
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