From ecc55ca8f4b7da2200074a01f5ce5264634cc30d Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Wed, 31 Oct 2012 09:39:32 +0000 Subject: Added @asfaltboy. Thanks! --- docs/topics/credits.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/topics/credits.md b/docs/topics/credits.md index 69d57802..a74f7983 100644 --- a/docs/topics/credits.md +++ b/docs/topics/credits.md @@ -51,6 +51,7 @@ The following people have helped make REST framework great. * Daniel Vaca Araujo - [diviei] * Madis Väin - [madisvain] * Stephan Groß - [minddust] +* Pavel Savchenko - [asfaltboy] Many thanks to everyone who's contributed to the project. @@ -136,4 +137,5 @@ To contact the author directly: [rdobson]: https://github.com/rdobson [diviei]: https://github.com/diviei [madisvain]: https://github.com/madisvain -[minddust]: https://github.com/minddust \ No newline at end of file +[minddust]: https://github.com/minddust +[asfaltboy]: https://github.com/asfaltboy -- cgit v1.2.3 From 027c9079f62322fe933bdfd4438f23cf4848e3cc Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Wed, 31 Oct 2012 20:11:32 +0000 Subject: PUT as create should return 201. Fixes #340. --- docs/topics/release-notes.md | 4 ++++ rest_framework/mixins.py | 7 +++---- rest_framework/tests/generics.py | 6 +++--- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/docs/topics/release-notes.md b/docs/topics/release-notes.md index a466f4b1..b336aeab 100644 --- a/docs/topics/release-notes.md +++ b/docs/topics/release-notes.md @@ -4,6 +4,10 @@ > > — Eric S. Raymond, [The Cathedral and the Bazaar][cite]. +## Master + +* If PUT creates an instance return '201 Created', instead of '200 OK'. + ## 2.0.0 * **Fix all of the things.** (Well, almost.) diff --git a/rest_framework/mixins.py b/rest_framework/mixins.py index 8873e4ae..0f2a0d93 100644 --- a/rest_framework/mixins.py +++ b/rest_framework/mixins.py @@ -3,9 +3,6 @@ Basic building blocks for generic class based views. We don't bind behaviour to http method handlers yet, which allows mixin classes to be composed in interesting ways. - -Eg. Use mixins to build a Resource class, and have a Router class - perform the binding of http methods to actions for us. """ from django.http import Http404 from rest_framework import status @@ -78,15 +75,17 @@ class UpdateModelMixin(object): def update(self, request, *args, **kwargs): try: self.object = self.get_object() + success_status = status.HTTP_200_OK except Http404: self.object = None + success_status = status.HTTP_201_CREATED serializer = self.get_serializer(data=request.DATA, instance=self.object) if serializer.is_valid(): self.pre_save(serializer.object) self.object = serializer.save() - return Response(serializer.data) + return Response(serializer.data, status=success_status) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) diff --git a/rest_framework/tests/generics.py b/rest_framework/tests/generics.py index d45ea976..a8279ef2 100644 --- a/rest_framework/tests/generics.py +++ b/rest_framework/tests/generics.py @@ -236,7 +236,7 @@ class TestInstanceView(TestCase): request = factory.put('/1', json.dumps(content), content_type='application/json') response = self.view(request, pk=1).render() - self.assertEquals(response.status_code, status.HTTP_200_OK) + self.assertEquals(response.status_code, status.HTTP_201_CREATED) self.assertEquals(response.data, {'id': 1, 'text': 'foobar'}) updated = self.objects.get(id=1) self.assertEquals(updated.text, 'foobar') @@ -251,7 +251,7 @@ class TestInstanceView(TestCase): request = factory.put('/5', json.dumps(content), content_type='application/json') response = self.view(request, pk=5).render() - self.assertEquals(response.status_code, status.HTTP_200_OK) + self.assertEquals(response.status_code, status.HTTP_201_CREATED) new_obj = self.objects.get(pk=5) self.assertEquals(new_obj.text, 'foobar') @@ -264,7 +264,7 @@ class TestInstanceView(TestCase): request = factory.put('/test_slug', json.dumps(content), content_type='application/json') response = self.slug_based_view(request, slug='test_slug').render() - self.assertEquals(response.status_code, status.HTTP_200_OK) + self.assertEquals(response.status_code, status.HTTP_201_CREATED) self.assertEquals(response.data, {'slug': 'test_slug', 'text': 'foobar'}) new_obj = SlugBasedModel.objects.get(slug='test_slug') self.assertEquals(new_obj.text, 'foobar') -- cgit v1.2.3 From 96dc9ce1ad15275944a5fd9389843a30c6aff3c6 Mon Sep 17 00:00:00 2001 From: Otto Yiu Date: Wed, 31 Oct 2012 21:27:21 -0700 Subject: Fixing documentation on auth/throttling guides --- docs/api-guide/authentication.md | 6 +++--- docs/api-guide/throttling.md | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/api-guide/authentication.md b/docs/api-guide/authentication.md index 889d16c0..3137b9d4 100644 --- a/docs/api-guide/authentication.md +++ b/docs/api-guide/authentication.md @@ -30,7 +30,7 @@ The default authentication policy may be set globally, using the `DEFAULT_AUTHEN REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( - 'rest_framework.authentication.UserBasicAuthentication', + 'rest_framework.authentication.BasicAuthentication', 'rest_framework.authentication.SessionAuthentication', ) } @@ -38,7 +38,7 @@ The default authentication policy may be set globally, using the `DEFAULT_AUTHEN You can also set the authentication policy on a per-view basis, using the `APIView` class based views. class ExampleView(APIView): - authentication_classes = (SessionAuthentication, UserBasicAuthentication) + authentication_classes = (SessionAuthentication, BasicAuthentication) permission_classes = (IsAuthenticated,) def get(self, request, format=None): @@ -51,7 +51,7 @@ You can also set the authentication policy on a per-view basis, using the `APIVi Or, if you're using the `@api_view` decorator with function based views. @api_view(['GET']) - @authentication_classes((SessionAuthentication, UserBasicAuthentication)) + @authentication_classes((SessionAuthentication, BasicAuthentication)) @permissions_classes((IsAuthenticated,)) def example_view(request, format=None): content = { diff --git a/docs/api-guide/throttling.md b/docs/api-guide/throttling.md index bfda7079..b03bc9e0 100644 --- a/docs/api-guide/throttling.md +++ b/docs/api-guide/throttling.md @@ -31,8 +31,8 @@ The default throttling policy may be set globally, using the `DEFAULT_THROTTLE_C REST_FRAMEWORK = { 'DEFAULT_THROTTLE_CLASSES': ( - 'rest_framework.throttles.AnonThrottle', - 'rest_framework.throttles.UserThrottle' + 'rest_framework.throttling.AnonRateThrottle', + 'rest_framework.throttling.UserRateThrottle' ), 'DEFAULT_THROTTLE_RATES': { 'anon': '100/day', @@ -136,7 +136,7 @@ For example, given the following views... REST_FRAMEWORK = { 'DEFAULT_THROTTLE_CLASSES': ( - 'rest_framework.throttles.ScopedRateThrottle' + 'rest_framework.throttling.ScopedRateThrottle' ), 'DEFAULT_THROTTLE_RATES': { 'contacts': '1000/day', -- cgit v1.2.3 From 756297ad1d07f56459471bff041828850ace0496 Mon Sep 17 00:00:00 2001 From: Otto Yiu Date: Wed, 31 Oct 2012 21:40:20 -0700 Subject: fix 'from_native' method when rel is None 'NoneType' object has no attribute 'to' --- rest_framework/fields.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest_framework/fields.py b/rest_framework/fields.py index 1d6d760e..73c8f72b 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -211,9 +211,9 @@ class ModelField(WritableField): def from_native(self, value): try: rel = self.model_field.rel + return rel.to._meta.get_field(rel.field_name).to_python(value) except: return self.model_field.to_python(value) - return rel.to._meta.get_field(rel.field_name).to_python(value) def field_to_native(self, obj, field_name): value = self.model_field._get_val_from_obj(obj) -- cgit v1.2.3 From d3aedd5fb1d8c50e9b7047469163dc75ac3de022 Mon Sep 17 00:00:00 2001 From: Pavel Savchenko Date: Thu, 1 Nov 2012 15:00:22 +0200 Subject: return choices as unicode and not string, might as well have jsonp return unicode --- rest_framework/renderers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rest_framework/renderers.py b/rest_framework/renderers.py index 8dff0c77..fd6f9499 100644 --- a/rest_framework/renderers.py +++ b/rest_framework/renderers.py @@ -100,7 +100,7 @@ class JSONPRenderer(JSONRenderer): callback = self.get_callback(renderer_context) json = super(JSONPRenderer, self).render(data, accepted_media_type, renderer_context) - return "%s(%s);" % (callback, json) + return u"%s(%s);" % (callback, json) class XMLRenderer(BaseRenderer): @@ -306,7 +306,7 @@ class BrowsableAPIRenderer(BaseRenderer): if getattr(widget, 'choices', None): choices = widget.choices if any([ident != desc for (ident, desc) in choices]): - choices = [(ident, "%s (%s)" % (desc, ident)) + choices = [(ident, u"%s (%s)" % (desc, ident)) for (ident, desc) in choices] widget.choices = choices kwargs['widget'] = widget -- cgit v1.2.3 From 9a0cc7c720d40f7d2408672c49a5d8bfb62c3979 Mon Sep 17 00:00:00 2001 From: Pavel Savchenko Date: Thu, 1 Nov 2012 15:06:11 +0200 Subject: since MultipleObjectBaseView was renamed MultipleObjectAPIView, it stands to reason to complete the renaming in docs and comments as well. --- docs/tutorial/3-class-based-views.md | 4 ++-- rest_framework/mixins.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/tutorial/3-class-based-views.md b/docs/tutorial/3-class-based-views.md index a31dccb2..91ef4038 100644 --- a/docs/tutorial/3-class-based-views.md +++ b/docs/tutorial/3-class-based-views.md @@ -92,7 +92,7 @@ Let's take a look at how we can compose our views by using the mixin classes. class SnippetList(mixins.ListModelMixin, mixins.CreateModelMixin, - generics.MultipleObjectBaseView): + generics.MultipleObjectAPIView): model = Snippet serializer_class = SnippetSerializer @@ -102,7 +102,7 @@ Let's take a look at how we can compose our views by using the mixin classes. def post(self, request, *args, **kwargs): return self.create(request, *args, **kwargs) -We'll take a moment to examine exactly what's happening here - We're building our view using `MultipleObjectBaseView`, and adding in `ListModelMixin` and `CreateModelMixin`. +We'll take a moment to examine exactly what's happening here - We're building our view using `MultipleObjectAPIView`, and adding in `ListModelMixin` and `CreateModelMixin`. The base class provides the core functionality, and the mixin classes provide the `.list()` and `.create()` actions. We're then explicitly binding the `get` and `post` methods to the appropriate actions. Simple enough stuff so far. diff --git a/rest_framework/mixins.py b/rest_framework/mixins.py index 0f2a0d93..47e4edf7 100644 --- a/rest_framework/mixins.py +++ b/rest_framework/mixins.py @@ -29,7 +29,7 @@ class CreateModelMixin(object): class ListModelMixin(object): """ List a queryset. - Should be mixed in with `MultipleObjectBaseView`. + Should be mixed in with `MultipleObjectAPIView`. """ empty_error = u"Empty list and '%(class_name)s.allow_empty' is False." -- cgit v1.2.3 From 600289a8153eb70542551bab00d59fb7ff0065f0 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Thu, 1 Nov 2012 13:31:22 +0000 Subject: Added @ottoyiu. Thanks! --- docs/topics/credits.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/topics/credits.md b/docs/topics/credits.md index a74f7983..df022341 100644 --- a/docs/topics/credits.md +++ b/docs/topics/credits.md @@ -52,6 +52,7 @@ The following people have helped make REST framework great. * Madis Väin - [madisvain] * Stephan Groß - [minddust] * Pavel Savchenko - [asfaltboy] +* Otto Yiu - [ottoyiu] Many thanks to everyone who's contributed to the project. @@ -139,3 +140,4 @@ To contact the author directly: [madisvain]: https://github.com/madisvain [minddust]: https://github.com/minddust [asfaltboy]: https://github.com/asfaltboy +[ottoyiu]: https://github.com/OttoYiu -- cgit v1.2.3 From d327c5f531b341ad980d20454211b02b87f34d0e Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Thu, 1 Nov 2012 23:04:13 +0000 Subject: Relational field support in browseable API. Add slug relational fields. Add quickstart. --- djangorestframework.egg-info/PKG-INFO | 19 ++++ djangorestframework.egg-info/SOURCES.txt | 86 +++++++++++++++++ djangorestframework.egg-info/dependency_links.txt | 1 + djangorestframework.egg-info/top_level.txt | 7 ++ docs/index.md | 2 - docs/template.html | 2 +- docs/tutorial/quickstart.md | 9 +- rest_framework/fields.py | 107 ++++++++++++++++++++- rest_framework/renderers.py | 25 +++-- .../static/rest_framework/css/default.css | 7 ++ rest_framework/templates/rest_framework/base.html | 4 +- 11 files changed, 244 insertions(+), 25 deletions(-) create mode 100644 djangorestframework.egg-info/PKG-INFO create mode 100644 djangorestframework.egg-info/SOURCES.txt create mode 100644 djangorestframework.egg-info/dependency_links.txt create mode 100644 djangorestframework.egg-info/top_level.txt diff --git a/djangorestframework.egg-info/PKG-INFO b/djangorestframework.egg-info/PKG-INFO new file mode 100644 index 00000000..04eafbde --- /dev/null +++ b/djangorestframework.egg-info/PKG-INFO @@ -0,0 +1,19 @@ +Metadata-Version: 1.0 +Name: djangorestframework +Version: 2.0.0 +Summary: A lightweight REST framework for Django. +Home-page: http://django-rest-framework.org +Author: Tom Christie +Author-email: tom@tomchristie.com +License: BSD +Download-URL: http://pypi.python.org/pypi/rest_framework/ +Description: UNKNOWN +Platform: UNKNOWN +Classifier: Development Status :: 4 - Beta +Classifier: Environment :: Web Environment +Classifier: Framework :: Django +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Topic :: Internet :: WWW/HTTP diff --git a/djangorestframework.egg-info/SOURCES.txt b/djangorestframework.egg-info/SOURCES.txt new file mode 100644 index 00000000..298d1c33 --- /dev/null +++ b/djangorestframework.egg-info/SOURCES.txt @@ -0,0 +1,86 @@ +MANIFEST.in +setup.py +djangorestframework.egg-info/PKG-INFO +djangorestframework.egg-info/SOURCES.txt +djangorestframework.egg-info/dependency_links.txt +djangorestframework.egg-info/top_level.txt +rest_framework/__init__.py +rest_framework/authentication.py +rest_framework/compat.py +rest_framework/decorators.py +rest_framework/exceptions.py +rest_framework/fields.py +rest_framework/generics.py +rest_framework/mixins.py +rest_framework/models.py +rest_framework/negotiation.py +rest_framework/pagination.py +rest_framework/parsers.py +rest_framework/permissions.py +rest_framework/renderers.py +rest_framework/request.py +rest_framework/response.py +rest_framework/reverse.py +rest_framework/serializers.py +rest_framework/settings.py +rest_framework/status.py +rest_framework/throttling.py +rest_framework/urlpatterns.py +rest_framework/urls.py +rest_framework/views.py +rest_framework/authtoken/__init__.py +rest_framework/authtoken/models.py +rest_framework/authtoken/views.py +rest_framework/authtoken/migrations/0001_initial.py +rest_framework/authtoken/migrations/__init__.py +rest_framework/runtests/__init__.py +rest_framework/runtests/runcoverage.py +rest_framework/runtests/runtests.py +rest_framework/runtests/settings.py +rest_framework/runtests/urls.py +rest_framework/static/rest_framework/css/bootstrap-tweaks.css +rest_framework/static/rest_framework/css/bootstrap.min.css +rest_framework/static/rest_framework/css/default.css +rest_framework/static/rest_framework/css/prettify.css +rest_framework/static/rest_framework/img/glyphicons-halflings-white.png +rest_framework/static/rest_framework/img/glyphicons-halflings.png +rest_framework/static/rest_framework/img/grid.png +rest_framework/static/rest_framework/js/bootstrap.min.js +rest_framework/static/rest_framework/js/default.js +rest_framework/static/rest_framework/js/jquery-1.8.1-min.js +rest_framework/static/rest_framework/js/prettify-min.js +rest_framework/templates/rest_framework/api.html +rest_framework/templates/rest_framework/base.html +rest_framework/templates/rest_framework/login.html +rest_framework/templatetags/__init__.py +rest_framework/templatetags/rest_framework.py +rest_framework/tests/__init__.py +rest_framework/tests/authentication.py +rest_framework/tests/breadcrumbs.py +rest_framework/tests/decorators.py +rest_framework/tests/description.py +rest_framework/tests/files.py +rest_framework/tests/genericrelations.py +rest_framework/tests/generics.py +rest_framework/tests/htmlrenderer.py +rest_framework/tests/hyperlinkedserializers.py +rest_framework/tests/models.py +rest_framework/tests/modelviews.py +rest_framework/tests/negotiation.py +rest_framework/tests/pagination.py +rest_framework/tests/parsers.py +rest_framework/tests/renderers.py +rest_framework/tests/request.py +rest_framework/tests/response.py +rest_framework/tests/reverse.py +rest_framework/tests/serializer.py +rest_framework/tests/status.py +rest_framework/tests/testcases.py +rest_framework/tests/tests.py +rest_framework/tests/throttling.py +rest_framework/tests/validators.py +rest_framework/tests/views.py +rest_framework/utils/__init__.py +rest_framework/utils/breadcrumbs.py +rest_framework/utils/encoders.py +rest_framework/utils/mediatypes.py \ No newline at end of file diff --git a/djangorestframework.egg-info/dependency_links.txt b/djangorestframework.egg-info/dependency_links.txt new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/djangorestframework.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/djangorestframework.egg-info/top_level.txt b/djangorestframework.egg-info/top_level.txt new file mode 100644 index 00000000..7e18534d --- /dev/null +++ b/djangorestframework.egg-info/top_level.txt @@ -0,0 +1,7 @@ +rest_framework/authtoken +rest_framework/utils +rest_framework/tests +rest_framework/runtests +rest_framework/templatetags +rest_framework +rest_framework/authtoken/migrations diff --git a/docs/index.md b/docs/index.md index 75a1cf6e..5e086872 100644 --- a/docs/index.md +++ b/docs/index.md @@ -66,11 +66,9 @@ If you're intending to use the browseable API you'll want to add REST framework' Note that the URL path can be whatever you want, but you must include `rest_framework.urls` with the `rest_framework` namespace. - ## Tutorial diff --git a/docs/template.html b/docs/template.html index 94fc269f..c428dff3 100644 --- a/docs/template.html +++ b/docs/template.html @@ -53,7 +53,7 @@