aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/api-guide/exceptions.md4
-rwxr-xr-xdocs/api-guide/generic-views.md2
-rw-r--r--docs/topics/contributing.md2
-rw-r--r--rest_framework/authtoken/models.py7
-rw-r--r--rest_framework/exceptions.py2
-rw-r--r--rest_framework/fields.py3
-rw-r--r--rest_framework/serializers.py1
-rw-r--r--rest_framework/tests/test_fields.py9
-rw-r--r--rest_framework/tests/test_serializer.py29
9 files changed, 41 insertions, 18 deletions
diff --git a/docs/api-guide/exceptions.md b/docs/api-guide/exceptions.md
index 4e8b823c..66e18173 100644
--- a/docs/api-guide/exceptions.md
+++ b/docs/api-guide/exceptions.md
@@ -18,7 +18,7 @@ The handled exceptions are:
In each case, REST framework will return a response with an appropriate status code and content-type. The body of the response will include any additional details regarding the nature of the error.
-By default all error responses will include a key `details` in the body of the response, but other keys may also be included.
+By default all error responses will include a key `detail` in the body of the response, but other keys may also be included.
For example, the following request:
@@ -86,7 +86,7 @@ Note that the exception handler will only be called for responses generated by r
The **base class** for all exceptions raised inside REST framework.
-To provide a custom exception, subclass `APIException` and set the `.status_code` and `.detail` properties on the class.
+To provide a custom exception, subclass `APIException` and set the `.status_code` and `.default_detail` properties on the class.
For example, if your API relies on a third party service that may sometimes be unreachable, you might want to implement an exception for the "503 Service Unavailable" HTTP response code. You could do this like so:
diff --git a/docs/api-guide/generic-views.md b/docs/api-guide/generic-views.md
index e23b2c74..fb927ea8 100755
--- a/docs/api-guide/generic-views.md
+++ b/docs/api-guide/generic-views.md
@@ -119,7 +119,7 @@ For example:
self.check_object_permissions(self.request, obj)
return obj
-Note that if your API doesn't include any object level permissions, you may optionally exclude the ``self.check_object_permissions, and simply return the object from the `get_object_or_404` lookup.
+Note that if your API doesn't include any object level permissions, you may optionally exclude the `self.check_object_permissions`, and simply return the object from the `get_object_or_404` lookup.
#### `get_filter_backends(self)`
diff --git a/docs/topics/contributing.md b/docs/topics/contributing.md
index 30d292f8..5a5d1a80 100644
--- a/docs/topics/contributing.md
+++ b/docs/topics/contributing.md
@@ -60,7 +60,7 @@ To run the tests, clone the repository, and then:
# Setup the virtual environment
virtualenv env
- env/bin/activate
+ source env/bin/activate
pip install -r requirements.txt
pip install -r optionals.txt
diff --git a/rest_framework/authtoken/models.py b/rest_framework/authtoken/models.py
index 024f62bf..8eac2cc4 100644
--- a/rest_framework/authtoken/models.py
+++ b/rest_framework/authtoken/models.py
@@ -1,5 +1,5 @@
-import uuid
-import hmac
+import binascii
+import os
from hashlib import sha1
from django.conf import settings
from django.db import models
@@ -34,8 +34,7 @@ class Token(models.Model):
return super(Token, self).save(*args, **kwargs)
def generate_key(self):
- unique = uuid.uuid4()
- return hmac.new(unique.bytes, digestmod=sha1).hexdigest()
+ return binascii.hexlify(os.urandom(20))
def __unicode__(self):
return self.key
diff --git a/rest_framework/exceptions.py b/rest_framework/exceptions.py
index 4276625a..0ac5866e 100644
--- a/rest_framework/exceptions.py
+++ b/rest_framework/exceptions.py
@@ -12,7 +12,7 @@ import math
class APIException(Exception):
"""
Base class for REST framework exceptions.
- Subclasses should provide `.status_code` and `.detail` properties.
+ Subclasses should provide `.status_code` and `.default_detail` properties.
"""
status_code = status.HTTP_500_INTERNAL_SERVER_ERROR
default_detail = ''
diff --git a/rest_framework/fields.py b/rest_framework/fields.py
index 2f475d6e..05daaab7 100644
--- a/rest_framework/fields.py
+++ b/rest_framework/fields.py
@@ -477,7 +477,8 @@ class URLField(CharField):
type_label = 'url'
def __init__(self, **kwargs):
- kwargs['validators'] = [validators.URLValidator()]
+ if not 'validators' in kwargs:
+ kwargs['validators'] = [validators.URLValidator()]
super(URLField, self).__init__(**kwargs)
diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py
index 38b5089a..10256d47 100644
--- a/rest_framework/serializers.py
+++ b/rest_framework/serializers.py
@@ -893,6 +893,7 @@ class ModelSerializer(Serializer):
field_name = field.source or field_name
if field_name in exclusions \
and not field.read_only \
+ and field.required \
and not isinstance(field, Serializer):
exclusions.remove(field_name)
return exclusions
diff --git a/rest_framework/tests/test_fields.py b/rest_framework/tests/test_fields.py
index 5c96bce9..e127feef 100644
--- a/rest_framework/tests/test_fields.py
+++ b/rest_framework/tests/test_fields.py
@@ -860,7 +860,9 @@ class SlugFieldTests(TestCase):
class URLFieldTests(TestCase):
"""
- Tests for URLField attribute values
+ Tests for URLField attribute values.
+
+ (Includes test for #1210, checking that validators can be overridden.)
"""
class URLFieldModel(RESTFrameworkModel):
@@ -902,6 +904,11 @@ class URLFieldTests(TestCase):
self.assertEqual(getattr(serializer.fields['url_field'],
'max_length'), 20)
+ def test_validators_can_be_overridden(self):
+ url_field = serializers.URLField(validators=[])
+ validators = url_field.validators
+ self.assertEqual([], validators, 'Passing `validators` kwarg should have overridden default validators')
+
class FieldMetadata(TestCase):
def setUp(self):
diff --git a/rest_framework/tests/test_serializer.py b/rest_framework/tests/test_serializer.py
index 75d6e785..6b1e333e 100644
--- a/rest_framework/tests/test_serializer.py
+++ b/rest_framework/tests/test_serializer.py
@@ -71,6 +71,15 @@ class ActionItemSerializer(serializers.ModelSerializer):
class Meta:
model = ActionItem
+class ActionItemSerializerOptionalFields(serializers.ModelSerializer):
+ """
+ Intended to test that fields with `required=False` are excluded from validation.
+ """
+ title = serializers.CharField(required=False)
+
+ class Meta:
+ model = ActionItem
+ fields = ('title',)
class ActionItemSerializerCustomRestore(serializers.ModelSerializer):
@@ -288,7 +297,13 @@ class BasicTests(TestCase):
serializer.save()
self.assertIsNotNone(serializer.data.get('id',None), 'Model is saved. `id` should be set.')
-
+ def test_fields_marked_as_not_required_are_excluded_from_validation(self):
+ """
+ Check that fields with `required=False` are included in list of exclusions.
+ """
+ serializer = ActionItemSerializerOptionalFields(self.actionitem)
+ exclusions = serializer.get_validation_exclusions()
+ self.assertTrue('title' in exclusions, '`title` field was marked `required=False` and should be excluded')
class DictStyleSerializer(serializers.Serializer):
@@ -1808,14 +1823,14 @@ class SerializerDefaultTrueBoolean(TestCase):
self.assertEqual(serializer.data['cat'], False)
self.assertEqual(serializer.data['dog'], False)
-
+
class BoolenFieldTypeTest(TestCase):
'''
Ensure the various Boolean based model fields are rendered as the proper
field type
-
+
'''
-
+
def setUp(self):
'''
Setup an ActionItemSerializer for BooleanTesting
@@ -1831,11 +1846,11 @@ class BoolenFieldTypeTest(TestCase):
'''
bfield = self.serializer.get_fields()['done']
self.assertEqual(type(bfield), fields.BooleanField)
-
+
def test_nullbooleanfield_type(self):
'''
- Test that BooleanField is infered from models.NullBooleanField
-
+ Test that BooleanField is infered from models.NullBooleanField
+
https://groups.google.com/forum/#!topic/django-rest-framework/D9mXEftpuQ8
'''
bfield = self.serializer.get_fields()['started']