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
af53e34d
Commit
af53e34d
authored
Dec 15, 2014
by
Tom Christie
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2279 from tomchristie/fix-serializer-repr-unicode-bug
Use unicode internally everywhere for 'repr'.
parents
1f6fd924
dc66cce1
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
66 additions
and
21 deletions
+66
-21
rest_framework/compat.py
+17
-0
rest_framework/fields.py
+8
-4
rest_framework/serializers.py
+5
-5
rest_framework/utils/representation.py
+3
-1
rest_framework/utils/serializer_helpers.py
+4
-3
rest_framework/validators.py
+8
-6
tests/test_fields.py
+2
-2
tests/test_serializer.py
+19
-0
No files found.
rest_framework/compat.py
View file @
af53e34d
...
@@ -16,6 +16,23 @@ from django.utils import six
...
@@ -16,6 +16,23 @@ from django.utils import six
import
django
import
django
def
unicode_repr
(
instance
):
# Get the repr of an instance, but ensure it is a unicode string
# on both python 3 (already the case) and 2 (not the case).
if
six
.
PY2
:
repr
(
instance
)
.
decode
(
'utf-8'
)
return
repr
(
instance
)
def
unicode_to_repr
(
value
):
# Coerce a unicode string to the correct repr return type, depending on
# the Python version. We wrap all our `__repr__` implementations with
# this and then use unicode throughout internally.
if
six
.
PY2
:
return
value
.
encode
(
'utf-8'
)
return
value
# OrderedDict only available in Python 2.7.
# OrderedDict only available in Python 2.7.
# This will always be the case in Django 1.7 and above, as these versions
# This will always be the case in Django 1.7 and above, as these versions
# no longer support Python 2.6.
# no longer support Python 2.6.
...
...
rest_framework/fields.py
View file @
af53e34d
from
__future__
import
unicode_literals
from
django.conf
import
settings
from
django.conf
import
settings
from
django.core.exceptions
import
ObjectDoesNotExist
from
django.core.exceptions
import
ObjectDoesNotExist
from
django.core.exceptions
import
ValidationError
as
DjangoValidationError
from
django.core.exceptions
import
ValidationError
as
DjangoValidationError
...
@@ -10,7 +11,8 @@ from django.utils.translation import ugettext_lazy as _
...
@@ -10,7 +11,8 @@ from django.utils.translation import ugettext_lazy as _
from
rest_framework
import
ISO_8601
from
rest_framework
import
ISO_8601
from
rest_framework.compat
import
(
from
rest_framework.compat
import
(
EmailValidator
,
MinValueValidator
,
MaxValueValidator
,
EmailValidator
,
MinValueValidator
,
MaxValueValidator
,
MinLengthValidator
,
MaxLengthValidator
,
URLValidator
,
OrderedDict
MinLengthValidator
,
MaxLengthValidator
,
URLValidator
,
OrderedDict
,
unicode_repr
,
unicode_to_repr
)
)
from
rest_framework.exceptions
import
ValidationError
from
rest_framework.exceptions
import
ValidationError
from
rest_framework.settings
import
api_settings
from
rest_framework.settings
import
api_settings
...
@@ -113,7 +115,9 @@ class CreateOnlyDefault:
...
@@ -113,7 +115,9 @@ class CreateOnlyDefault:
return
self
.
default
return
self
.
default
def
__repr__
(
self
):
def
__repr__
(
self
):
return
'
%
s(
%
s)'
%
(
self
.
__class__
.
__name__
,
repr
(
self
.
default
))
return
unicode_to_repr
(
'
%
s(
%
s)'
%
(
self
.
__class__
.
__name__
,
unicode_repr
(
self
.
default
))
)
class
CurrentUserDefault
:
class
CurrentUserDefault
:
...
@@ -124,7 +128,7 @@ class CurrentUserDefault:
...
@@ -124,7 +128,7 @@ class CurrentUserDefault:
return
self
.
user
return
self
.
user
def
__repr__
(
self
):
def
__repr__
(
self
):
return
'
%
s()'
%
self
.
__class__
.
__name__
return
unicode_to_repr
(
'
%
s()'
%
self
.
__class__
.
__name__
)
class
SkipField
(
Exception
):
class
SkipField
(
Exception
):
...
@@ -463,7 +467,7 @@ class Field(object):
...
@@ -463,7 +467,7 @@ class Field(object):
This allows us to create descriptive representations for serializer
This allows us to create descriptive representations for serializer
instances that show all the declared fields on the serializer.
instances that show all the declared fields on the serializer.
"""
"""
return
representation
.
field_repr
(
self
)
return
unicode_to_repr
(
representation
.
field_repr
(
self
)
)
# Boolean types...
# Boolean types...
...
...
rest_framework/serializers.py
View file @
af53e34d
...
@@ -10,12 +10,11 @@ python primitives.
...
@@ -10,12 +10,11 @@ python primitives.
2. The process of marshalling between python primitives and request and
2. The process of marshalling between python primitives and request and
response content is handled by parsers and renderers.
response content is handled by parsers and renderers.
"""
"""
import
warnings
from
__future__
import
unicode_literals
from
django.db
import
models
from
django.db
import
models
from
django.db.models.fields
import
FieldDoesNotExist
from
django.db.models.fields
import
FieldDoesNotExist
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.translation
import
ugettext_lazy
as
_
from
rest_framework.compat
import
unicode_to_repr
from
rest_framework.utils
import
model_meta
from
rest_framework.utils
import
model_meta
from
rest_framework.utils.field_mapping
import
(
from
rest_framework.utils.field_mapping
import
(
get_url_kwargs
,
get_field_kwargs
,
get_url_kwargs
,
get_field_kwargs
,
...
@@ -29,6 +28,7 @@ from rest_framework.validators import (
...
@@ -29,6 +28,7 @@ from rest_framework.validators import (
UniqueForDateValidator
,
UniqueForMonthValidator
,
UniqueForYearValidator
,
UniqueForDateValidator
,
UniqueForMonthValidator
,
UniqueForYearValidator
,
UniqueTogetherValidator
UniqueTogetherValidator
)
)
import
warnings
# Note: We do the following so that users of the framework can use this style:
# Note: We do the following so that users of the framework can use this style:
...
@@ -396,7 +396,7 @@ class Serializer(BaseSerializer):
...
@@ -396,7 +396,7 @@ class Serializer(BaseSerializer):
return
attrs
return
attrs
def
__repr__
(
self
):
def
__repr__
(
self
):
return
representation
.
serializer_repr
(
self
,
indent
=
1
)
return
unicode_to_repr
(
representation
.
serializer_repr
(
self
,
indent
=
1
)
)
# The following are used for accessing `BoundField` instances on the
# The following are used for accessing `BoundField` instances on the
# serializer, for the purposes of presenting a form-like API onto the
# serializer, for the purposes of presenting a form-like API onto the
...
@@ -564,7 +564,7 @@ class ListSerializer(BaseSerializer):
...
@@ -564,7 +564,7 @@ class ListSerializer(BaseSerializer):
return
self
.
instance
return
self
.
instance
def
__repr__
(
self
):
def
__repr__
(
self
):
return
representation
.
list_repr
(
self
,
indent
=
1
)
return
unicode_to_repr
(
representation
.
list_repr
(
self
,
indent
=
1
)
)
# Include a backlink to the serializer class on return objects.
# Include a backlink to the serializer class on return objects.
# Allows renderers such as HTMLFormRenderer to get the full field info.
# Allows renderers such as HTMLFormRenderer to get the full field info.
...
...
rest_framework/utils/representation.py
View file @
af53e34d
...
@@ -2,9 +2,11 @@
...
@@ -2,9 +2,11 @@
Helper functions for creating user-friendly representations
Helper functions for creating user-friendly representations
of serializer classes and serializer fields.
of serializer classes and serializer fields.
"""
"""
from
__future__
import
unicode_literals
from
django.db
import
models
from
django.db
import
models
from
django.utils.encoding
import
force_text
from
django.utils.encoding
import
force_text
from
django.utils.functional
import
Promise
from
django.utils.functional
import
Promise
from
rest_framework.compat
import
unicode_repr
import
re
import
re
...
@@ -24,7 +26,7 @@ def smart_repr(value):
...
@@ -24,7 +26,7 @@ def smart_repr(value):
if
isinstance
(
value
,
Promise
)
and
value
.
_delegate_text
:
if
isinstance
(
value
,
Promise
)
and
value
.
_delegate_text
:
value
=
force_text
(
value
)
value
=
force_text
(
value
)
value
=
repr
(
value
)
value
=
unicode_
repr
(
value
)
# Representations like u'help text'
# Representations like u'help text'
# should simply be presented as 'help text'
# should simply be presented as 'help text'
...
...
rest_framework/utils/serializer_helpers.py
View file @
af53e34d
from
__future__
import
unicode_literals
import
collections
import
collections
from
rest_framework.compat
import
OrderedDict
from
rest_framework.compat
import
OrderedDict
,
unicode_to_repr
class
ReturnDict
(
OrderedDict
):
class
ReturnDict
(
OrderedDict
):
...
@@ -47,9 +48,9 @@ class BoundField(object):
...
@@ -47,9 +48,9 @@ class BoundField(object):
return
self
.
_field
.
__class__
return
self
.
_field
.
__class__
def
__repr__
(
self
):
def
__repr__
(
self
):
return
'<
%
s value=
%
s errors=
%
s>'
%
(
return
unicode_to_repr
(
'<
%
s value=
%
s errors=
%
s>'
%
(
self
.
__class__
.
__name__
,
self
.
value
,
self
.
errors
self
.
__class__
.
__name__
,
self
.
value
,
self
.
errors
)
)
)
class
NestedBoundField
(
BoundField
):
class
NestedBoundField
(
BoundField
):
...
...
rest_framework/validators.py
View file @
af53e34d
...
@@ -6,7 +6,9 @@ This gives us better separation of concerns, allows us to use single-step
...
@@ -6,7 +6,9 @@ This gives us better separation of concerns, allows us to use single-step
object creation, and makes it possible to switch between using the implicit
object creation, and makes it possible to switch between using the implicit
`ModelSerializer` class and an equivalent explicit `Serializer` class.
`ModelSerializer` class and an equivalent explicit `Serializer` class.
"""
"""
from
__future__
import
unicode_literals
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.translation
import
ugettext_lazy
as
_
from
rest_framework.compat
import
unicode_to_repr
from
rest_framework.exceptions
import
ValidationError
from
rest_framework.exceptions
import
ValidationError
from
rest_framework.utils.representation
import
smart_repr
from
rest_framework.utils.representation
import
smart_repr
...
@@ -59,10 +61,10 @@ class UniqueValidator:
...
@@ -59,10 +61,10 @@ class UniqueValidator:
raise
ValidationError
(
self
.
message
)
raise
ValidationError
(
self
.
message
)
def
__repr__
(
self
):
def
__repr__
(
self
):
return
'<
%
s(queryset=
%
s)>'
%
(
return
unicode_to_repr
(
'<
%
s(queryset=
%
s)>'
%
(
self
.
__class__
.
__name__
,
self
.
__class__
.
__name__
,
smart_repr
(
self
.
queryset
)
smart_repr
(
self
.
queryset
)
)
)
)
class
UniqueTogetherValidator
:
class
UniqueTogetherValidator
:
...
@@ -141,11 +143,11 @@ class UniqueTogetherValidator:
...
@@ -141,11 +143,11 @@ class UniqueTogetherValidator:
raise
ValidationError
(
self
.
message
.
format
(
field_names
=
field_names
))
raise
ValidationError
(
self
.
message
.
format
(
field_names
=
field_names
))
def
__repr__
(
self
):
def
__repr__
(
self
):
return
'<
%
s(queryset=
%
s, fields=
%
s)>'
%
(
return
unicode_to_repr
(
'<
%
s(queryset=
%
s, fields=
%
s)>'
%
(
self
.
__class__
.
__name__
,
self
.
__class__
.
__name__
,
smart_repr
(
self
.
queryset
),
smart_repr
(
self
.
queryset
),
smart_repr
(
self
.
fields
)
smart_repr
(
self
.
fields
)
)
)
)
class
BaseUniqueForValidator
:
class
BaseUniqueForValidator
:
...
@@ -205,12 +207,12 @@ class BaseUniqueForValidator:
...
@@ -205,12 +207,12 @@ class BaseUniqueForValidator:
raise
ValidationError
({
self
.
field
:
message
})
raise
ValidationError
({
self
.
field
:
message
})
def
__repr__
(
self
):
def
__repr__
(
self
):
return
'<
%
s(queryset=
%
s, field=
%
s, date_field=
%
s)>'
%
(
return
unicode_to_repr
(
'<
%
s(queryset=
%
s, field=
%
s, date_field=
%
s)>'
%
(
self
.
__class__
.
__name__
,
self
.
__class__
.
__name__
,
smart_repr
(
self
.
queryset
),
smart_repr
(
self
.
queryset
),
smart_repr
(
self
.
field
),
smart_repr
(
self
.
field
),
smart_repr
(
self
.
date_field
)
smart_repr
(
self
.
date_field
)
)
)
)
class
UniqueForDateValidator
(
BaseUniqueForValidator
):
class
UniqueForDateValidator
(
BaseUniqueForValidator
):
...
...
tests/test_fields.py
View file @
af53e34d
...
@@ -62,7 +62,7 @@ class TestEmpty:
...
@@ -62,7 +62,7 @@ class TestEmpty:
"""
"""
field
=
serializers
.
CharField
(
allow_blank
=
True
)
field
=
serializers
.
CharField
(
allow_blank
=
True
)
output
=
field
.
run_validation
(
''
)
output
=
field
.
run_validation
(
''
)
assert
output
is
''
assert
output
==
''
def
test_default
(
self
):
def
test_default
(
self
):
"""
"""
...
@@ -817,7 +817,7 @@ class TestChoiceField(FieldValues):
...
@@ -817,7 +817,7 @@ class TestChoiceField(FieldValues):
]
]
)
)
output
=
field
.
run_validation
(
''
)
output
=
field
.
run_validation
(
''
)
assert
output
is
''
assert
output
==
''
class
TestChoiceFieldWithType
(
FieldValues
):
class
TestChoiceFieldWithType
(
FieldValues
):
...
...
tests/test_serializer.py
View file @
af53e34d
# coding: utf-8
from
__future__
import
unicode_literals
from
__future__
import
unicode_literals
from
rest_framework
import
serializers
from
rest_framework
import
serializers
from
rest_framework.compat
import
unicode_repr
import
pytest
import
pytest
...
@@ -197,3 +199,20 @@ class TestIncorrectlyConfigured:
...
@@ -197,3 +199,20 @@ class TestIncorrectlyConfigured:
"The serializer field might be named incorrectly and not match any attribute or key on the `ExampleObject` instance.
\n
"
"The serializer field might be named incorrectly and not match any attribute or key on the `ExampleObject` instance.
\n
"
"Original exception text was:"
"Original exception text was:"
)
)
class
TestUnicodeRepr
:
def
test_unicode_repr
(
self
):
class
ExampleSerializer
(
serializers
.
Serializer
):
example
=
serializers
.
CharField
()
class
ExampleObject
:
def
__init__
(
self
):
self
.
example
=
'한국'
def
__repr__
(
self
):
return
unicode_repr
(
self
.
example
)
instance
=
ExampleObject
()
serializer
=
ExampleSerializer
(
instance
)
repr
(
serializer
)
# Should not error.
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