diff options
| -rw-r--r-- | docs/api-guide/exceptions.md | 4 | ||||
| -rwxr-xr-x | docs/api-guide/generic-views.md | 2 | ||||
| -rw-r--r-- | docs/topics/contributing.md | 2 | ||||
| -rw-r--r-- | rest_framework/authtoken/models.py | 7 | ||||
| -rw-r--r-- | rest_framework/exceptions.py | 2 | ||||
| -rw-r--r-- | rest_framework/fields.py | 3 | ||||
| -rw-r--r-- | rest_framework/serializers.py | 1 | ||||
| -rw-r--r-- | rest_framework/tests/test_fields.py | 9 | ||||
| -rw-r--r-- | rest_framework/tests/test_serializer.py | 29 |
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'] |
