Commit 343fd5ec by Tom Christie

Merge branch 'canassa-method-not-allowed-not-raised' into remove-content-overriding

parents 4b4130e8 66e37220
...@@ -360,6 +360,10 @@ HTTP Signature (currently a [IETF draft][http-signature-ietf-draft]) provides a ...@@ -360,6 +360,10 @@ HTTP Signature (currently a [IETF draft][http-signature-ietf-draft]) provides a
[Django-rest-auth][django-rest-auth] library provides a set of REST API endpoints for registration, authentication (including social media authentication), password reset, retrieve and update user details, etc. By having these API endpoints, your client apps such as AngularJS, iOS, Android, and others can communicate to your Django backend site independently via REST APIs for user management. [Django-rest-auth][django-rest-auth] library provides a set of REST API endpoints for registration, authentication (including social media authentication), password reset, retrieve and update user details, etc. By having these API endpoints, your client apps such as AngularJS, iOS, Android, and others can communicate to your Django backend site independently via REST APIs for user management.
## django-rest-knox
[Django-rest-knox][django-rest-knox] library provides models and views to handle token based authentication in a more secure and extensible way than the built-in TokenAuthentication scheme - with Single Page Applications and Mobile clients in mind. It provides per-client tokens, and views to generate them when provided some other authentication (usually basic authentication), to delete the token (providing a server enforced logout) and to delete all tokens (logs out all clients that a user is logged into).
[cite]: http://jacobian.org/writing/rest-worst-practices/ [cite]: http://jacobian.org/writing/rest-worst-practices/
[http401]: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2 [http401]: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2
[http403]: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.4 [http403]: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.4
...@@ -400,3 +404,4 @@ HTTP Signature (currently a [IETF draft][http-signature-ietf-draft]) provides a ...@@ -400,3 +404,4 @@ HTTP Signature (currently a [IETF draft][http-signature-ietf-draft]) provides a
[mac]: http://tools.ietf.org/html/draft-hammer-oauth-v2-mac-token-05 [mac]: http://tools.ietf.org/html/draft-hammer-oauth-v2-mac-token-05
[djoser]: https://github.com/sunscrapers/djoser [djoser]: https://github.com/sunscrapers/djoser
[django-rest-auth]: https://github.com/Tivix/django-rest-auth [django-rest-auth]: https://github.com/Tivix/django-rest-auth
[django-rest-knox]: https://github.com/James1345/django-rest-knox
...@@ -1032,6 +1032,9 @@ The following third party packages are also available. ...@@ -1032,6 +1032,9 @@ The following third party packages are also available.
The [django-rest-marshmallow][django-rest-marshmallow] package provides an alternative implementation for serializers, using the python [marshmallow][marshmallow] library. It exposes the same API as the REST framework serializers, and can be used as a drop-in replacement in some use-cases. The [django-rest-marshmallow][django-rest-marshmallow] package provides an alternative implementation for serializers, using the python [marshmallow][marshmallow] library. It exposes the same API as the REST framework serializers, and can be used as a drop-in replacement in some use-cases.
## Serpy
The [serpy][serpy] package is an alternative implementation for serializers that is built for speed. [Serpy][serpy] serializes complex datatypes to simple native types. The native types can be easily converted to JSON or any other format needed.
## MongoengineModelSerializer ## MongoengineModelSerializer
The [django-rest-framework-mongoengine][mongoengine] package provides a `MongoEngineModelSerializer` serializer class that supports using MongoDB as the storage layer for Django REST framework. The [django-rest-framework-mongoengine][mongoengine] package provides a `MongoEngineModelSerializer` serializer class that supports using MongoDB as the storage layer for Django REST framework.
...@@ -1050,6 +1053,7 @@ The [django-rest-framework-hstore][django-rest-framework-hstore] package provide ...@@ -1050,6 +1053,7 @@ The [django-rest-framework-hstore][django-rest-framework-hstore] package provide
[encapsulation-blogpost]: http://www.dabapps.com/blog/django-models-and-encapsulation/ [encapsulation-blogpost]: http://www.dabapps.com/blog/django-models-and-encapsulation/
[django-rest-marshmallow]: http://tomchristie.github.io/django-rest-marshmallow/ [django-rest-marshmallow]: http://tomchristie.github.io/django-rest-marshmallow/
[marshmallow]: https://marshmallow.readthedocs.org/en/latest/ [marshmallow]: https://marshmallow.readthedocs.org/en/latest/
[serpy]: https://github.com/clarkduvall/serpy
[mongoengine]: https://github.com/umutbozkurt/django-rest-framework-mongoengine [mongoengine]: https://github.com/umutbozkurt/django-rest-framework-mongoengine
[django-rest-framework-gis]: https://github.com/djangonauts/django-rest-framework-gis [django-rest-framework-gis]: https://github.com/djangonauts/django-rest-framework-gis
[django-rest-framework-hstore]: https://github.com/djangonauts/django-rest-framework-hstore [django-rest-framework-hstore]: https://github.com/djangonauts/django-rest-framework-hstore
......
...@@ -181,7 +181,7 @@ We can also serialize querysets instead of model instances. To do so we simply ...@@ -181,7 +181,7 @@ We can also serialize querysets instead of model instances. To do so we simply
serializer = SnippetSerializer(Snippet.objects.all(), many=True) serializer = SnippetSerializer(Snippet.objects.all(), many=True)
serializer.data serializer.data
# [{'pk': 1, 'title': u'', 'code': u'foo = "bar"\n', 'linenos': False, 'language': u'python', 'style': u'friendly'}, {'pk': 2, 'title': u'', 'code': u'print "hello, world"\n', 'linenos': False, 'language': u'python', 'style': u'friendly'}] # [OrderedDict([('pk', 1), ('title', u''), ('code', u'foo = "bar"\n'), ('linenos', False), ('language', 'python'), ('style', 'friendly')]), OrderedDict([('pk', 2), ('title', u''), ('code', u'print "hello, world"\n'), ('linenos', False), ('language', 'python'), ('style', 'friendly')]), OrderedDict([('pk', 3), ('title', u''), ('code', u'print "hello, world"'), ('linenos', False), ('language', 'python'), ('style', 'friendly')])]
## Using ModelSerializers ## Using ModelSerializers
......
...@@ -5,4 +5,4 @@ wheel==0.24.0 ...@@ -5,4 +5,4 @@ wheel==0.24.0
twine==1.4.0 twine==1.4.0
# Transifex client for managing translation resources. # Transifex client for managing translation resources.
transifex-client==0.10 transifex-client==0.11b3
...@@ -608,10 +608,13 @@ class BooleanField(Field): ...@@ -608,10 +608,13 @@ class BooleanField(Field):
super(BooleanField, self).__init__(**kwargs) super(BooleanField, self).__init__(**kwargs)
def to_internal_value(self, data): def to_internal_value(self, data):
try:
if data in self.TRUE_VALUES: if data in self.TRUE_VALUES:
return True return True
elif data in self.FALSE_VALUES: elif data in self.FALSE_VALUES:
return False return False
except TypeError: # Input is an unhashable type
pass
self.fail('invalid', input=data) self.fail('invalid', input=data)
def to_representation(self, value): def to_representation(self, value):
......
...@@ -466,6 +466,18 @@ class TestBooleanField(FieldValues): ...@@ -466,6 +466,18 @@ class TestBooleanField(FieldValues):
} }
field = serializers.BooleanField() field = serializers.BooleanField()
def test_disallow_unhashable_collection_types(self):
inputs = (
[],
{},
)
field = serializers.BooleanField()
for input_value in inputs:
with pytest.raises(serializers.ValidationError) as exc_info:
field.run_validation(input_value)
expected = ['"{0}" is not a valid boolean.'.format(input_value)]
assert exc_info.value.detail == expected
class TestNullBooleanField(FieldValues): class TestNullBooleanField(FieldValues):
""" """
......
...@@ -5,6 +5,7 @@ from django.test import TestCase ...@@ -5,6 +5,7 @@ from django.test import TestCase
from django.utils import six from django.utils import six
from rest_framework import generics, routers, serializers, status, viewsets from rest_framework import generics, routers, serializers, status, viewsets
from rest_framework.parsers import JSONParser
from rest_framework.renderers import ( from rest_framework.renderers import (
BaseRenderer, BrowsableAPIRenderer, JSONRenderer BaseRenderer, BrowsableAPIRenderer, JSONRenderer
) )
...@@ -79,6 +80,14 @@ class MockViewSettingContentType(APIView): ...@@ -79,6 +80,14 @@ class MockViewSettingContentType(APIView):
return Response(DUMMYCONTENT, status=DUMMYSTATUS, content_type='setbyview') return Response(DUMMYCONTENT, status=DUMMYSTATUS, content_type='setbyview')
class JSONView(APIView):
parser_classes = (JSONParser,)
def post(self, request, **kwargs):
assert request.data
return Response(DUMMYCONTENT)
class HTMLView(APIView): class HTMLView(APIView):
renderer_classes = (BrowsableAPIRenderer, ) renderer_classes = (BrowsableAPIRenderer, )
...@@ -114,6 +123,7 @@ urlpatterns = [ ...@@ -114,6 +123,7 @@ urlpatterns = [
url(r'^.*\.(?P<format>.+)$', MockView.as_view(renderer_classes=[RendererA, RendererB, RendererC])), url(r'^.*\.(?P<format>.+)$', MockView.as_view(renderer_classes=[RendererA, RendererB, RendererC])),
url(r'^$', MockView.as_view(renderer_classes=[RendererA, RendererB, RendererC])), url(r'^$', MockView.as_view(renderer_classes=[RendererA, RendererB, RendererC])),
url(r'^html$', HTMLView.as_view()), url(r'^html$', HTMLView.as_view()),
url(r'^json$', JSONView.as_view()),
url(r'^html1$', HTMLView1.as_view()), url(r'^html1$', HTMLView1.as_view()),
url(r'^html_new_model$', HTMLNewModelView.as_view()), url(r'^html_new_model$', HTMLNewModelView.as_view()),
url(r'^html_new_model_viewset', include(new_model_viewset_router.urls)), url(r'^html_new_model_viewset', include(new_model_viewset_router.urls)),
...@@ -203,6 +213,25 @@ class RendererIntegrationTests(TestCase): ...@@ -203,6 +213,25 @@ class RendererIntegrationTests(TestCase):
self.assertEqual(resp.status_code, DUMMYSTATUS) self.assertEqual(resp.status_code, DUMMYSTATUS)
class UnsupportedMediaTypeTests(TestCase):
urls = 'tests.test_response'
def test_should_allow_posting_json(self):
response = self.client.post('/json', data='{"test": 123}', content_type='application/json')
self.assertEqual(response.status_code, 200)
def test_should_not_allow_posting_xml(self):
response = self.client.post('/json', data='<test>123</test>', content_type='application/xml')
self.assertEqual(response.status_code, 415)
def test_should_not_allow_posting_a_form(self):
response = self.client.post('/json', data={'test': 123})
self.assertEqual(response.status_code, 415)
class Issue122Tests(TestCase): class Issue122Tests(TestCase):
""" """
Tests that covers #122. Tests that covers #122.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment