mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-26 11:33:59 +03:00
Merge master
This commit is contained in:
commit
b6ee784240
|
@ -104,7 +104,7 @@ This permission is suitable if you want your API to only be accessible to regist
|
||||||
|
|
||||||
The `IsAdminUser` permission class will deny permission to any user, unless `user.is_staff` is `True` in which case permission will be allowed.
|
The `IsAdminUser` permission class will deny permission to any user, unless `user.is_staff` is `True` in which case permission will be allowed.
|
||||||
|
|
||||||
This permission is suitable is you want your API to only be accessible to a subset of trusted administrators.
|
This permission is suitable if you want your API to only be accessible to a subset of trusted administrators.
|
||||||
|
|
||||||
## IsAuthenticatedOrReadOnly
|
## IsAuthenticatedOrReadOnly
|
||||||
|
|
||||||
|
|
|
@ -181,7 +181,7 @@ Similarly, we can control the format of the request that we send, using the `Con
|
||||||
"id": 4,
|
"id": 4,
|
||||||
"title": "",
|
"title": "",
|
||||||
"code": "print 456",
|
"code": "print 456",
|
||||||
"linenos": true,
|
"linenos": false,
|
||||||
"language": "python",
|
"language": "python",
|
||||||
"style": "friendly"
|
"style": "friendly"
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
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 _
|
||||||
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:
|
||||||
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:
|
||||||
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):
|
||||||
|
@ -382,13 +386,23 @@ class Field(object):
|
||||||
"""
|
"""
|
||||||
Transform the *incoming* primitive data into a native value.
|
Transform the *incoming* primitive data into a native value.
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError('to_internal_value() must be implemented.')
|
raise NotImplementedError(
|
||||||
|
'{cls}.to_internal_value() must be implemented.'.format(
|
||||||
|
cls=self.__class__.__name__
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
def to_representation(self, value):
|
def to_representation(self, value):
|
||||||
"""
|
"""
|
||||||
Transform the *outgoing* native value into primitive data.
|
Transform the *outgoing* native value into primitive data.
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError('to_representation() must be implemented.')
|
raise NotImplementedError(
|
||||||
|
'{cls}.to_representation() must be implemented.\n'
|
||||||
|
'If you are upgrading from REST framework version 2 '
|
||||||
|
'you might want `ReadOnlyField`.'.format(
|
||||||
|
cls=self.__class__.__name__
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
def fail(self, key, **kwargs):
|
def fail(self, key, **kwargs):
|
||||||
"""
|
"""
|
||||||
|
@ -453,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...
|
||||||
|
|
|
@ -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 (
|
||||||
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):
|
||||||
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):
|
||||||
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.
|
||||||
|
|
|
@ -6,6 +6,7 @@ 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
|
||||||
|
|
||||||
|
|
||||||
|
@ -25,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).decode('utf-8')
|
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'
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
|
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):
|
||||||
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):
|
||||||
|
|
|
@ -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:
|
||||||
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:
|
||||||
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:
|
||||||
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):
|
||||||
|
|
|
@ -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):
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
output = field.run_validation('')
|
output = field.run_validation('')
|
||||||
assert output is ''
|
assert output == ''
|
||||||
|
|
||||||
|
|
||||||
class TestChoiceFieldWithType(FieldValues):
|
class TestChoiceFieldWithType(FieldValues):
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
# coding: utf-8
|
# 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
|
||||||
|
|
||||||
|
|
||||||
|
@ -208,9 +209,10 @@ class TestUnicodeRepr:
|
||||||
class ExampleObject:
|
class ExampleObject:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.example = '한국'
|
self.example = '한국'
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return self.example.encode('utf8')
|
return unicode_repr(self.example)
|
||||||
|
|
||||||
instance = ExampleObject()
|
instance = ExampleObject()
|
||||||
serializer = ExampleSerializer(instance)
|
serializer = ExampleSerializer(instance)
|
||||||
repr(serializer)
|
repr(serializer) # Should not error.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user