mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-01-24 16:24:18 +03:00
Merge branch 'canassa-method-not-allowed-not-raised' into remove-content-overriding
This commit is contained in:
commit
343fd5ec3d
|
@ -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-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/
|
||||
[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
|
||||
|
@ -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
|
||||
[djoser]: https://github.com/sunscrapers/djoser
|
||||
[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.
|
|||
|
||||
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
|
||||
|
||||
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
|
|||
[encapsulation-blogpost]: http://www.dabapps.com/blog/django-models-and-encapsulation/
|
||||
[django-rest-marshmallow]: http://tomchristie.github.io/django-rest-marshmallow/
|
||||
[marshmallow]: https://marshmallow.readthedocs.org/en/latest/
|
||||
[serpy]: https://github.com/clarkduvall/serpy
|
||||
[mongoengine]: https://github.com/umutbozkurt/django-rest-framework-mongoengine
|
||||
[django-rest-framework-gis]: https://github.com/djangonauts/django-rest-framework-gis
|
||||
[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
|
|||
|
||||
serializer = SnippetSerializer(Snippet.objects.all(), many=True)
|
||||
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
|
||||
|
||||
|
|
|
@ -5,4 +5,4 @@ wheel==0.24.0
|
|||
twine==1.4.0
|
||||
|
||||
# Transifex client for managing translation resources.
|
||||
transifex-client==0.10
|
||||
transifex-client==0.11b3
|
||||
|
|
|
@ -608,10 +608,13 @@ class BooleanField(Field):
|
|||
super(BooleanField, self).__init__(**kwargs)
|
||||
|
||||
def to_internal_value(self, data):
|
||||
if data in self.TRUE_VALUES:
|
||||
return True
|
||||
elif data in self.FALSE_VALUES:
|
||||
return False
|
||||
try:
|
||||
if data in self.TRUE_VALUES:
|
||||
return True
|
||||
elif data in self.FALSE_VALUES:
|
||||
return False
|
||||
except TypeError: # Input is an unhashable type
|
||||
pass
|
||||
self.fail('invalid', input=data)
|
||||
|
||||
def to_representation(self, value):
|
||||
|
|
|
@ -466,6 +466,18 @@ class TestBooleanField(FieldValues):
|
|||
}
|
||||
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):
|
||||
"""
|
||||
|
|
|
@ -5,6 +5,7 @@ from django.test import TestCase
|
|||
from django.utils import six
|
||||
|
||||
from rest_framework import generics, routers, serializers, status, viewsets
|
||||
from rest_framework.parsers import JSONParser
|
||||
from rest_framework.renderers import (
|
||||
BaseRenderer, BrowsableAPIRenderer, JSONRenderer
|
||||
)
|
||||
|
@ -79,6 +80,14 @@ class MockViewSettingContentType(APIView):
|
|||
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):
|
||||
renderer_classes = (BrowsableAPIRenderer, )
|
||||
|
||||
|
@ -114,6 +123,7 @@ urlpatterns = [
|
|||
url(r'^.*\.(?P<format>.+)$', 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'^json$', JSONView.as_view()),
|
||||
url(r'^html1$', HTMLView1.as_view()),
|
||||
url(r'^html_new_model$', HTMLNewModelView.as_view()),
|
||||
url(r'^html_new_model_viewset', include(new_model_viewset_router.urls)),
|
||||
|
@ -203,6 +213,25 @@ class RendererIntegrationTests(TestCase):
|
|||
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):
|
||||
"""
|
||||
Tests that covers #122.
|
||||
|
|
Loading…
Reference in New Issue
Block a user