From af8a362d6b513b71de45109b441f79ed7d1b103c Mon Sep 17 00:00:00 2001 From: Nicolas Delaby Date: Mon, 7 Apr 2014 14:59:27 +0200 Subject: reset stored credentials when call client.logout() --- rest_framework/test.py | 4 ++++ rest_framework/tests/test_testing.py | 11 +++++++++++ 2 files changed, 15 insertions(+) diff --git a/rest_framework/test.py b/rest_framework/test.py index df5a5b3b..79982cb0 100644 --- a/rest_framework/test.py +++ b/rest_framework/test.py @@ -154,6 +154,10 @@ class APIClient(APIRequestFactory, DjangoClient): kwargs.update(self._credentials) return super(APIClient, self).request(**kwargs) + def logout(self): + self._credentials = {} + return super(APIClient, self).logout() + class APITransactionTestCase(testcases.TransactionTestCase): client_class = APIClient diff --git a/rest_framework/tests/test_testing.py b/rest_framework/tests/test_testing.py index a55d4b22..b16d1962 100644 --- a/rest_framework/tests/test_testing.py +++ b/rest_framework/tests/test_testing.py @@ -99,6 +99,17 @@ class TestAPITestClient(TestCase): self.assertEqual(response.status_code, 403) self.assertEqual(response.data, expected) + def test_can_logout(self): + """ + `logout()` reset stored credentials + """ + self.client.credentials(HTTP_AUTHORIZATION='example') + response = self.client.get('/view/') + self.assertEqual(response.data['auth'], 'example') + self.client.logout() + response = self.client.get('/view/') + self.assertEqual(response.data['auth'], b'') + class TestAPIRequestFactory(TestCase): def test_csrf_exempt_by_default(self): -- cgit v1.2.3 From b4c7717cb80cb13a2f13aae8855e226685306880 Mon Sep 17 00:00:00 2001 From: Walt Javins Date: Fri, 13 Jun 2014 22:26:00 -0700 Subject: Refactor login template to extend base. While experimenting with extending DRF, I found that the login page 1) had no title, and 2) duplicated info from base.html. This change adds a new {% block body %} to the base.html template which allows override of the entire html . login_base.html has its duplicated head info stripped, and now extends base.html to share common html templating. As part of this change, pretify.css is unnecessarily added to login_base.html. If this is deemed a problem, it will be easy to block that css out, and have login_base.html override the block. Ideally, I would have liked to create a new api_base.html that extends base.html, move the api specific logic into that template, and leave base.html content agnostic, to truely be a unifying base for all DRF pages. But this change would break current apps that override api.html and expect base.html to be the immediate super template. :/ This change is benificial because it: - removes duplication of header declarations (mostly css includes) - adds a html title to the login page - standardizes html header info across all DRF pages Docs are updated to reflect the new structure. --- docs/topics/browsable-api.md | 1 + rest_framework/templates/rest_framework/base.html | 2 ++ rest_framework/templates/rest_framework/login_base.html | 15 +++------------ 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/docs/topics/browsable-api.md b/docs/topics/browsable-api.md index e32db695..ffa0b07d 100644 --- a/docs/topics/browsable-api.md +++ b/docs/topics/browsable-api.md @@ -69,6 +69,7 @@ For more specific CSS tweaks than simply overriding the default bootstrap theme All of the blocks available in the browsable API base template that can be used in your `api.html`. +* `body` - The entire html ``. * `bodyclass` - Class attribute for the `` tag, empty by default. * `bootstrap_theme` - CSS for the Bootstrap theme. * `bootstrap_navbar_variant` - CSS class for the navbar. diff --git a/rest_framework/templates/rest_framework/base.html b/rest_framework/templates/rest_framework/base.html index 7067ee2f..1f3def8f 100644 --- a/rest_framework/templates/rest_framework/base.html +++ b/rest_framework/templates/rest_framework/base.html @@ -24,6 +24,7 @@ {% endblock %} + {% block body %}
@@ -230,4 +231,5 @@ {% endblock %} + {% endblock %} diff --git a/rest_framework/templates/rest_framework/login_base.html b/rest_framework/templates/rest_framework/login_base.html index be9a0072..312a1138 100644 --- a/rest_framework/templates/rest_framework/login_base.html +++ b/rest_framework/templates/rest_framework/login_base.html @@ -1,17 +1,8 @@ +{% extends "rest_framework/base.html" %} {% load url from future %} {% load rest_framework %} - - - - {% block style %} - {% block bootstrap_theme %} - - - {% endblock %} - - {% endblock %} - + {% block body %}
@@ -50,4 +41,4 @@
- + {% endblock %} -- cgit v1.2.3 From 18eab53e892f2f579fd0bb4e1ca3cb47a074accc Mon Sep 17 00:00:00 2001 From: Emmanouil Date: Wed, 9 Jul 2014 15:53:31 +0100 Subject: Updated quick start project set up order --- docs/tutorial/quickstart.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/tutorial/quickstart.md b/docs/tutorial/quickstart.md index 8bf8c7f5..04792c69 100644 --- a/docs/tutorial/quickstart.md +++ b/docs/tutorial/quickstart.md @@ -6,8 +6,8 @@ We're going to create a simple API to allow admin users to view and edit the use Create a new Django project named `tutorial`, then start a new app called `quickstart`. - # Set up a new project - django-admin.py startproject tutorial + # Create the project directory + mkdir tutorial cd tutorial # Create a virtualenv to isolate our package dependencies locally @@ -18,6 +18,9 @@ Create a new Django project named `tutorial`, then start a new app called `quick pip install django pip install djangorestframework + # Set up a new project + django-admin.py startproject tutorial + # Create a new app python manage.py startapp quickstart -- cgit v1.2.3 From 05882cc5999088ac232788ae62717c061e74ad12 Mon Sep 17 00:00:00 2001 From: Ron Cohen Date: Fri, 25 Jul 2014 10:55:53 +0000 Subject: Sending "Bearer" and "Bearer " resulted in a 500. --- rest_framework/authentication.py | 14 +++++++------- rest_framework/tests/test_authentication.py | 9 +++++++++ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/rest_framework/authentication.py b/rest_framework/authentication.py index da9ca510..887ef5d7 100644 --- a/rest_framework/authentication.py +++ b/rest_framework/authentication.py @@ -310,6 +310,13 @@ class OAuth2Authentication(BaseAuthentication): auth = get_authorization_header(request).split() + if len(auth) == 1: + msg = 'Invalid bearer header. No credentials provided.' + raise exceptions.AuthenticationFailed(msg) + elif len(auth) > 2: + msg = 'Invalid bearer header. Token string should not contain spaces.' + raise exceptions.AuthenticationFailed(msg) + if auth and auth[0].lower() == b'bearer': access_token = auth[1] elif 'access_token' in request.POST: @@ -319,13 +326,6 @@ class OAuth2Authentication(BaseAuthentication): else: return None - if len(auth) == 1: - msg = 'Invalid bearer header. No credentials provided.' - raise exceptions.AuthenticationFailed(msg) - elif len(auth) > 2: - msg = 'Invalid bearer header. Token string should not contain spaces.' - raise exceptions.AuthenticationFailed(msg) - return self.authenticate_credentials(request, access_token) def authenticate_credentials(self, request, access_token): diff --git a/rest_framework/tests/test_authentication.py b/rest_framework/tests/test_authentication.py index a1c43d9c..cf8415ed 100644 --- a/rest_framework/tests/test_authentication.py +++ b/rest_framework/tests/test_authentication.py @@ -549,6 +549,15 @@ class OAuth2Tests(TestCase): response = self.csrf_client.get('/oauth2-test/', HTTP_AUTHORIZATION=auth) self.assertEqual(response.status_code, 401) + @unittest.skipUnless(oauth2_provider, 'django-oauth2-provider not installed') + def test_get_form_with_wrong_authorization_header_token_missing(self): + """Ensure that a wrong token lead to the correct HTTP error status code""" + auth = "Bearer" + response = self.csrf_client.get('/oauth2-test/', {}, HTTP_AUTHORIZATION=auth) + self.assertEqual(response.status_code, 401) + response = self.csrf_client.get('/oauth2-test/', HTTP_AUTHORIZATION=auth) + self.assertEqual(response.status_code, 401) + @unittest.skipUnless(oauth2_provider, 'django-oauth2-provider not installed') def test_get_form_passing_auth(self): """Ensure GETing form over OAuth with correct client credentials succeed""" -- cgit v1.2.3 From e3aff6a5678d48a2e328c9bb44b7c3de81caffd5 Mon Sep 17 00:00:00 2001 From: Ron Cohen Date: Fri, 25 Jul 2014 13:38:42 +0000 Subject: Updated test docstring related to missing bearer token. --- rest_framework/tests/test_authentication.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest_framework/tests/test_authentication.py b/rest_framework/tests/test_authentication.py index cf8415ed..34bf2910 100644 --- a/rest_framework/tests/test_authentication.py +++ b/rest_framework/tests/test_authentication.py @@ -551,7 +551,7 @@ class OAuth2Tests(TestCase): @unittest.skipUnless(oauth2_provider, 'django-oauth2-provider not installed') def test_get_form_with_wrong_authorization_header_token_missing(self): - """Ensure that a wrong token lead to the correct HTTP error status code""" + """Ensure that a missing token lead to the correct HTTP error status code""" auth = "Bearer" response = self.csrf_client.get('/oauth2-test/', {}, HTTP_AUTHORIZATION=auth) self.assertEqual(response.status_code, 401) -- cgit v1.2.3 From 48b02f016a827bc254aba2aedb81b472189c2165 Mon Sep 17 00:00:00 2001 From: Kyle Valade Date: Sun, 27 Jul 2014 14:01:43 -0700 Subject: Issue #1707: Add documentation to api-docs.viewsets notifying users that they should use the get_queryset() method when overriding a ModelViewSet method, such as list(). Otherwise, since queryset is a static property, the value will be cached for every instance of that ViewSet. --- docs/api-guide/viewsets.md | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/docs/api-guide/viewsets.md b/docs/api-guide/viewsets.md index 23b16575..774e11b7 100644 --- a/docs/api-guide/viewsets.md +++ b/docs/api-guide/viewsets.md @@ -70,6 +70,21 @@ There are two main advantages of using a `ViewSet` class over using a `View` cla Both of these come with a trade-off. Using regular views and URL confs is more explicit and gives you more control. ViewSets are helpful if you want to get up and running quickly, or when you have a large API and you want to enforce a consistent URL configuration throughout. +## Overriding ModelViewSet Methods + +Overriding the ModelViewSet is the same as overriding anything else, except you will need to remember to clone `self.queryset` before you use it, which you can do by using the built-in `get_queryset` method. For example: + + class UserViewSet(viewsets.ModelViewSet): + """ + A viewset for viewing and editing user instances. + """ + queryset = User.objects.all() + + def list(self, request): + queryset = self.get_queryset() + serializer = UserSerializer(queryset, many=True) + return Response(serializer.data) + ## Marking extra methods for routing The default routers included with REST framework will provide routes for a standard set of create/retrieve/update/destroy style operations, as shown below: @@ -142,7 +157,7 @@ The `@action` decorator will route `POST` requests by default, but may also acce @action(methods=['POST', 'DELETE']) def unset_password(self, request, pk=None): ... - + The two new actions will then be available at the urls `^users/{pk}/set_password/$` and `^users/{pk}/unset_password/$` -- cgit v1.2.3 From fe048dc4fbf064b11d7247061c931bb1038cc774 Mon Sep 17 00:00:00 2001 From: Xavier Ordoquy Date: Mon, 28 Jul 2014 07:37:30 +0200 Subject: Fix #1712 (issue when django-guardian is installed but not configured/used) --- rest_framework/compat.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/rest_framework/compat.py b/rest_framework/compat.py index fdf12448..9ad8b0d2 100644 --- a/rest_framework/compat.py +++ b/rest_framework/compat.py @@ -48,12 +48,15 @@ try: except ImportError: django_filters = None -# guardian is optional -try: - import guardian - import guardian.shortcuts # Fixes #1624 -except ImportError: - guardian = None +# Django-guardian is optional. Import only if guardian is in INSTALLED_APPS +# Fixes (#1712). We keep the try/except for the test suite. +guardian = None +if 'guardian' in settings.INSTALLED_APPS: + try: + import guardian + import guardian.shortcuts # Fixes #1624 + except ImportError: + pass # cStringIO only if it's available, otherwise StringIO -- cgit v1.2.3 From 5429c2800e263d27094ffa814589674b1b02d4f6 Mon Sep 17 00:00:00 2001 From: Xavier Ordoquy Date: Mon, 28 Jul 2014 08:00:50 +0200 Subject: Django-guardian version cleanup. --- .travis.yml | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index b2da9e81..7f1fda83 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ python: - "3.4" env: - - DJANGO="https://www.djangoproject.com/download/1.7.b4/tarball/" + - DJANGO="https://www.djangoproject.com/download/1.7c2/tarball/" - DJANGO="django==1.6.5" - DJANGO="django==1.5.8" - DJANGO="django==1.4.13" @@ -16,15 +16,13 @@ env: install: - pip install $DJANGO - - pip install defusedxml==0.3 Pillow==2.3.0 + - pip install defusedxml==0.3 Pillow==2.3.0 django-guardian==1.2.3 - "if [[ ${TRAVIS_PYTHON_VERSION::1} != '3' ]]; then pip install oauth2==1.5.211; fi" - "if [[ ${TRAVIS_PYTHON_VERSION::1} != '3' ]]; then pip install django-oauth-plus==2.2.4; fi" - "if [[ ${TRAVIS_PYTHON_VERSION::1} != '3' ]]; then pip install django-oauth2-provider==0.2.4; fi" - - "if [[ ${TRAVIS_PYTHON_VERSION::1} != '3' ]]; then pip install django-guardian==1.1.1; fi" - "if [[ ${DJANGO::11} == 'django==1.3' ]]; then pip install django-filter==0.5.4; fi" - "if [[ ${DJANGO::11} != 'django==1.3' ]]; then pip install django-filter==0.7; fi" - - "if [[ ${TRAVIS_PYTHON_VERSION::1} == '3' ]]; then pip install -e git+https://github.com/linovia/django-guardian.git@feature/django_1_7#egg=django-guardian-1.2.0; fi" - - "if [[ ${DJANGO} == 'https://www.djangoproject.com/download/1.7.b4/tarball/' ]]; then pip install -e git+https://github.com/linovia/django-guardian.git@feature/django_1_7#egg=django-guardian-1.2.0; fi" + - "if [[ ${DJANGO} == 'https://www.djangoproject.com/download/1.7c2/tarball/' ]]; then pip install -e git+https://github.com/linovia/django-guardian.git@feature/django_1_7#egg=django-guardian-1.2.0; fi" - export PYTHONPATH=. script: @@ -33,7 +31,7 @@ script: matrix: exclude: - python: "2.6" - env: DJANGO="https://www.djangoproject.com/download/1.7.b4/tarball/" + env: DJANGO="https://www.djangoproject.com/download/1.7c2/tarball/" - python: "3.2" env: DJANGO="django==1.4.13" - python: "3.2" -- cgit v1.2.3 From 0cbdbd24e57fbe58b90d77e454594a49a5f357b8 Mon Sep 17 00:00:00 2001 From: Xavier Ordoquy Date: Mon, 28 Jul 2014 13:54:43 +0200 Subject: Updated the tox file. --- tox.ini | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/tox.ini b/tox.ini index 279f79cc..72d156f9 100644 --- a/tox.ini +++ b/tox.ini @@ -12,34 +12,34 @@ commands = {envpython} rest_framework/runtests/runtests.py [testenv:py3.4-django1.7] basepython = python3.4 -deps = https://www.djangoproject.com/download/1.7b2/tarball/ +deps = https://www.djangoproject.com/download/1.7c2/tarball/ django-filter==0.7 defusedxml==0.3 Pillow==2.3.0 [testenv:py3.3-django1.7] basepython = python3.3 -deps = https://www.djangoproject.com/download/1.7b2/tarball/ +deps = https://www.djangoproject.com/download/1.7c2/tarball/ django-filter==0.7 defusedxml==0.3 Pillow==2.3.0 [testenv:py3.2-django1.7] basepython = python3.2 -deps = https://www.djangoproject.com/download/1.7b2/tarball/ +deps = https://www.djangoproject.com/download/1.7c2/tarball/ django-filter==0.7 defusedxml==0.3 Pillow==2.3.0 [testenv:py2.7-django1.7] basepython = python2.7 -deps = https://www.djangoproject.com/download/1.7b2/tarball/ +deps = https://www.djangoproject.com/download/1.7c2/tarball/ django-filter==0.7 defusedxml==0.3 - django-oauth-plus==2.2.1 - oauth2==1.5.211 - django-oauth2-provider==0.2.4 - django-guardian==1.1.1 + # django-oauth-plus==2.2.1 + # oauth2==1.5.211 + # django-oauth2-provider==0.2.4 + django-guardian==1.2.3 Pillow==2.3.0 [testenv:py3.4-django1.6] @@ -71,7 +71,7 @@ deps = Django==1.6.3 django-oauth-plus==2.2.1 oauth2==1.5.211 django-oauth2-provider==0.2.4 - django-guardian==1.1.1 + django-guardian==1.2.3 Pillow==2.3.0 [testenv:py2.6-django1.6] @@ -82,7 +82,7 @@ deps = Django==1.6.3 django-oauth-plus==2.2.1 oauth2==1.5.211 django-oauth2-provider==0.2.4 - django-guardian==1.1.1 + django-guardian==1.2.3 Pillow==2.3.0 [testenv:py3.4-django1.5] @@ -114,7 +114,7 @@ deps = django==1.5.6 django-oauth-plus==2.2.1 oauth2==1.5.211 django-oauth2-provider==0.2.3 - django-guardian==1.1.1 + django-guardian==1.2.3 Pillow==2.3.0 [testenv:py2.6-django1.5] @@ -125,7 +125,7 @@ deps = django==1.5.6 django-oauth-plus==2.2.1 oauth2==1.5.211 django-oauth2-provider==0.2.3 - django-guardian==1.1.1 + django-guardian==1.2.3 Pillow==2.3.0 [testenv:py2.7-django1.4] @@ -136,7 +136,7 @@ deps = django==1.4.11 django-oauth-plus==2.2.1 oauth2==1.5.211 django-oauth2-provider==0.2.3 - django-guardian==1.1.1 + django-guardian==1.2.3 Pillow==2.3.0 [testenv:py2.6-django1.4] @@ -147,7 +147,7 @@ deps = django==1.4.11 django-oauth-plus==2.2.1 oauth2==1.5.211 django-oauth2-provider==0.2.3 - django-guardian==1.1.1 + django-guardian==1.2.3 Pillow==2.3.0 [testenv:py2.7-django1.3] @@ -158,7 +158,7 @@ deps = django==1.3.5 django-oauth-plus==2.2.1 oauth2==1.5.211 django-oauth2-provider==0.2.3 - django-guardian==1.1.1 + django-guardian==1.2.3 Pillow==2.3.0 [testenv:py2.6-django1.3] @@ -169,5 +169,5 @@ deps = django==1.3.5 django-oauth-plus==2.2.1 oauth2==1.5.211 django-oauth2-provider==0.2.3 - django-guardian==1.1.1 + django-guardian==1.2.3 Pillow==2.3.0 -- cgit v1.2.3 From e40ffd60d44d736d7e27ff454cba1905f0becc26 Mon Sep 17 00:00:00 2001 From: Kyle Date: Mon, 28 Jul 2014 10:11:40 -0700 Subject: Issue #1707 - Add documentation about the caching of `GenericAPIView.queryset` to the `queryset` property, `get_queryset()`, and do generic-views.md; remove changes to the viewsets.md documentation from my last commit. --- docs/api-guide/generic-views.md | 8 +++++++- docs/api-guide/viewsets.md | 15 --------------- rest_framework/generics.py | 8 ++++++++ 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/docs/api-guide/generic-views.md b/docs/api-guide/generic-views.md index 7d06f246..b76c18cf 100755 --- a/docs/api-guide/generic-views.md +++ b/docs/api-guide/generic-views.md @@ -43,6 +43,12 @@ For more complex cases you might also want to override various methods on the vi return 20 return 100 + def list(self, request): + # Note the use of `get_queryset()` instead of `self.queryset` + queryset = self.get_queryset() + serializer = UserSerializer(queryset, many=True) + return Response(serializer.data) + For very simple cases you might want to pass through any class attributes using the `.as_view()` method. For example, your URLconf might include something the following entry. url(r'^/users/', ListCreateAPIView.as_view(model=User), name='user-list') @@ -63,7 +69,7 @@ Each of the concrete generic views provided is built by combining `GenericAPIVie The following attributes control the basic view behavior. -* `queryset` - The queryset that should be used for returning objects from this view. Typically, you must either set this attribute, or override the `get_queryset()` method. +* `queryset` - The queryset that should be used for returning objects from this view. Typically, you must either set this attribute, or override the `get_queryset()` method. If you are overriding a view method, it is important that you call `get_queryset()` instead of accessing this property directly, as `queryset` will get evaluated once, and those results will be cached for all subsequent requests. * `serializer_class` - The serializer class that should be used for validating and deserializing input, and for serializing output. Typically, you must either set this attribute, or override the `get_serializer_class()` method. * `lookup_field` - The model field that should be used to for performing object lookup of individual model instances. Defaults to `'pk'`. Note that when using hyperlinked APIs you'll need to ensure that *both* the API views *and* the serializer classes set the lookup fields if you need to use a custom value. * `lookup_url_kwarg` - The URL keyword argument that should be used for object lookup. The URL conf should include a keyword argument corresponding to this value. If unset this defaults to using the same value as `lookup_field`. diff --git a/docs/api-guide/viewsets.md b/docs/api-guide/viewsets.md index 774e11b7..4f345abb 100644 --- a/docs/api-guide/viewsets.md +++ b/docs/api-guide/viewsets.md @@ -70,21 +70,6 @@ There are two main advantages of using a `ViewSet` class over using a `View` cla Both of these come with a trade-off. Using regular views and URL confs is more explicit and gives you more control. ViewSets are helpful if you want to get up and running quickly, or when you have a large API and you want to enforce a consistent URL configuration throughout. -## Overriding ModelViewSet Methods - -Overriding the ModelViewSet is the same as overriding anything else, except you will need to remember to clone `self.queryset` before you use it, which you can do by using the built-in `get_queryset` method. For example: - - class UserViewSet(viewsets.ModelViewSet): - """ - A viewset for viewing and editing user instances. - """ - queryset = User.objects.all() - - def list(self, request): - queryset = self.get_queryset() - serializer = UserSerializer(queryset, many=True) - return Response(serializer.data) - ## Marking extra methods for routing The default routers included with REST framework will provide routes for a standard set of create/retrieve/update/destroy style operations, as shown below: diff --git a/rest_framework/generics.py b/rest_framework/generics.py index 7bac510f..65ccd952 100644 --- a/rest_framework/generics.py +++ b/rest_framework/generics.py @@ -43,6 +43,10 @@ class GenericAPIView(views.APIView): # You'll need to either set these attributes, # or override `get_queryset()`/`get_serializer_class()`. + # If you are overriding a view method, it is important that you call + # `get_queryset()` instead of accessing the `queryset` property directly, + # as `queryset` will get evaluated only once, and those results are cached + # for all subsequent requests. queryset = None serializer_class = None @@ -256,6 +260,10 @@ class GenericAPIView(views.APIView): This must be an iterable, and may be a queryset. Defaults to using `self.queryset`. + This method should always be used rather than accessing `self.queryset` + directly, as `self.queryset` gets evaluated only once, and those results + are cached for all subsequent requests. + You may want to override this if you need to provide different querysets depending on the incoming request. -- cgit v1.2.3 From fc8eb76c2259ea64a19876f040db4d93e834d39d Mon Sep 17 00:00:00 2001 From: Kyle Date: Mon, 28 Jul 2014 10:19:42 -0700 Subject: Issue #1707 - Add info about queryset property caching to get_queryset() docs. Add documentation to the get_queryset() method of generic-views.md regarding the caching of the queryset property. --- docs/api-guide/generic-views.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/api-guide/generic-views.md b/docs/api-guide/generic-views.md index b76c18cf..43c5782f 100755 --- a/docs/api-guide/generic-views.md +++ b/docs/api-guide/generic-views.md @@ -99,6 +99,8 @@ The following attributes are used to control pagination when used with list view Returns the queryset that should be used for list views, and that should be used as the base for lookups in detail views. Defaults to returning the queryset specified by the `queryset` attribute, or the default queryset for the model if the `model` shortcut is being used. +This method should always be used rather than accessing `self.queryset` directly, as `self.queryset` gets evaluated only once, and those results are cached for all subsequent requests. + May be overridden to provide dynamic behavior such as returning a queryset that is specific to the user making the request. For example: -- cgit v1.2.3 From 4210fedd211eaff80d139a4967577621282f520b Mon Sep 17 00:00:00 2001 From: Xavier Ordoquy Date: Tue, 29 Jul 2014 08:35:00 +0200 Subject: Fixed the cache issue with Django 1.7 rc* --- rest_framework/response.py | 1 + 1 file changed, 1 insertion(+) diff --git a/rest_framework/response.py b/rest_framework/response.py index 1dc6abcf..77cbb07c 100644 --- a/rest_framework/response.py +++ b/rest_framework/response.py @@ -15,6 +15,7 @@ class Response(SimpleTemplateResponse): An HttpResponse that allows its data to be rendered into arbitrary media types. """ + rendering_attrs = SimpleTemplateResponse.rendering_attrs + ['_closable_objects'] def __init__(self, data=None, status=200, template_name=None, headers=None, -- cgit v1.2.3 From 59d0a0387d907260ef8f91bbbca618831abd75a3 Mon Sep 17 00:00:00 2001 From: Xavier Ordoquy Date: Tue, 29 Jul 2014 10:20:10 +0200 Subject: Fixed the Django 1.3 compat --- rest_framework/response.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/rest_framework/response.py b/rest_framework/response.py index 77cbb07c..3928ca91 100644 --- a/rest_framework/response.py +++ b/rest_framework/response.py @@ -5,6 +5,7 @@ it is initialized with unrendered data, instead of a pre-rendered string. The appropriate renderer is called during Django's template response rendering. """ from __future__ import unicode_literals +import django from django.core.handlers.wsgi import STATUS_CODE_TEXT from django.template.response import SimpleTemplateResponse from rest_framework.compat import six @@ -15,7 +16,9 @@ class Response(SimpleTemplateResponse): An HttpResponse that allows its data to be rendered into arbitrary media types. """ - rendering_attrs = SimpleTemplateResponse.rendering_attrs + ['_closable_objects'] + # TODO: remove that once Django 1.3 isn't supported + if django.VERSION > (1, 3): + rendering_attrs = SimpleTemplateResponse.rendering_attrs + ['_closable_objects'] def __init__(self, data=None, status=200, template_name=None, headers=None, -- cgit v1.2.3 From 5e02f015b81bd743f6ee78f8414eca4e93eaab82 Mon Sep 17 00:00:00 2001 From: Xavier Ordoquy Date: Tue, 29 Jul 2014 10:30:08 +0200 Subject: Better fix for the Django 1.3 compat --- rest_framework/response.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest_framework/response.py b/rest_framework/response.py index 3928ca91..5c02ea50 100644 --- a/rest_framework/response.py +++ b/rest_framework/response.py @@ -17,7 +17,7 @@ class Response(SimpleTemplateResponse): arbitrary media types. """ # TODO: remove that once Django 1.3 isn't supported - if django.VERSION > (1, 3): + if django.VERSION >= (1, 4): rendering_attrs = SimpleTemplateResponse.rendering_attrs + ['_closable_objects'] def __init__(self, data=None, status=200, -- cgit v1.2.3 From 57d6e04ff5512f11594e29bf49c47b610594666c Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Wed, 30 Jul 2014 12:50:36 +0100 Subject: Add django-rest-framework-mongoengine link. Closes #1722 Closes #1562 Closes #1545 --- docs/api-guide/serializers.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/api-guide/serializers.md b/docs/api-guide/serializers.md index cedf1ff7..72568e53 100644 --- a/docs/api-guide/serializers.md +++ b/docs/api-guide/serializers.md @@ -580,7 +580,16 @@ The following custom model serializer could be used as a base class for model se def get_pk_field(self, model_field): return None +--- + +# Third party packages + +The following third party packages are also available. + +## 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. [cite]: https://groups.google.com/d/topic/django-users/sVFaOfQi4wY/discussion [relations]: relations.md +[mongoengine]: https://github.com/umutbozkurt/django-rest-framework-mongoengine -- cgit v1.2.3 From 80444165230f019b09d7f19d31c49fbdd68b744d Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Thu, 31 Jul 2014 20:19:28 +0100 Subject: Add platinum sponsors --- docs/css/default.css | 31 ++++++++++++++++++++++++++ docs/img/sponsors/0-eventbrite.png | Bin 0 -> 22429 bytes docs/img/sponsors/1-cyan.png | Bin 0 -> 6121 bytes docs/img/sponsors/1-divio.png | Bin 0 -> 4864 bytes docs/img/sponsors/1-kuwaitnet.png | Bin 0 -> 15489 bytes docs/img/sponsors/1-lulu.png | Bin 0 -> 18013 bytes docs/img/sponsors/1-potato.png | Bin 0 -> 12190 bytes docs/img/sponsors/1-purplebit.png | Bin 0 -> 9161 bytes docs/img/sponsors/1-runscope.png | Bin 0 -> 10913 bytes docs/img/sponsors/1-simple-energy.png | Bin 0 -> 54455 bytes docs/img/sponsors/1-vokal_interactive.png | Bin 0 -> 12532 bytes docs/img/sponsors/1-wiredrive.png | Bin 0 -> 8082 bytes docs/img/sponsors/2-byte.png | Bin 0 -> 13690 bytes docs/img/sponsors/2-crate.png | Bin 0 -> 8257 bytes docs/img/sponsors/2-heroku.png | Bin 0 -> 7337 bytes docs/img/sponsors/2-hipflask.png | Bin 0 -> 6016 bytes docs/img/sponsors/2-hipo.png | Bin 0 -> 8111 bytes docs/img/sponsors/2-koordinates.png | Bin 0 -> 1934 bytes docs/img/sponsors/2-laterpay.png | Bin 0 -> 2003 bytes docs/img/sponsors/2-lightning_kite.png | Bin 0 -> 6715 bytes docs/img/sponsors/2-mirus_research.png | Bin 0 -> 12414 bytes docs/img/sponsors/2-opbeat.png | Bin 0 -> 11603 bytes docs/img/sponsors/2-schuberg_philis.png | Bin 0 -> 21870 bytes docs/img/sponsors/2-vinta.png | Bin 0 -> 9918 bytes docs/img/sponsors/3-blimp.png | Bin 0 -> 6241 bytes docs/img/sponsors/3-gizmag.png | Bin 0 -> 5370 bytes docs/img/sponsors/3-imt_computer_services.png | Bin 0 -> 70397 bytes docs/img/sponsors/3-infinite_code.png | Bin 0 -> 21786 bytes docs/img/sponsors/3-life_the_game.png | Bin 0 -> 5485 bytes docs/img/sponsors/3-pkgfarm.png | Bin 0 -> 2275 bytes docs/img/sponsors/3-providenz.png | Bin 0 -> 12580 bytes docs/img/sponsors/3-shippo.png | Bin 0 -> 7345 bytes docs/img/sponsors/3-thermondo-gmbh.png | Bin 0 -> 20046 bytes docs/img/sponsors/3-tivix.png | Bin 0 -> 4091 bytes docs/img/sponsors/3-triggered_messaging.png | Bin 0 -> 10509 bytes docs/img/sponsors/3-wildfish.png | Bin 0 -> 4137 bytes docs/topics/kickstarter-announcement.md | 29 ++++++++++++++++++++++++ 37 files changed, 60 insertions(+) create mode 100644 docs/img/sponsors/0-eventbrite.png create mode 100644 docs/img/sponsors/1-cyan.png create mode 100644 docs/img/sponsors/1-divio.png create mode 100644 docs/img/sponsors/1-kuwaitnet.png create mode 100644 docs/img/sponsors/1-lulu.png create mode 100644 docs/img/sponsors/1-potato.png create mode 100644 docs/img/sponsors/1-purplebit.png create mode 100644 docs/img/sponsors/1-runscope.png create mode 100644 docs/img/sponsors/1-simple-energy.png create mode 100644 docs/img/sponsors/1-vokal_interactive.png create mode 100644 docs/img/sponsors/1-wiredrive.png create mode 100644 docs/img/sponsors/2-byte.png create mode 100644 docs/img/sponsors/2-crate.png create mode 100644 docs/img/sponsors/2-heroku.png create mode 100644 docs/img/sponsors/2-hipflask.png create mode 100644 docs/img/sponsors/2-hipo.png create mode 100644 docs/img/sponsors/2-koordinates.png create mode 100644 docs/img/sponsors/2-laterpay.png create mode 100644 docs/img/sponsors/2-lightning_kite.png create mode 100644 docs/img/sponsors/2-mirus_research.png create mode 100644 docs/img/sponsors/2-opbeat.png create mode 100644 docs/img/sponsors/2-schuberg_philis.png create mode 100644 docs/img/sponsors/2-vinta.png create mode 100644 docs/img/sponsors/3-blimp.png create mode 100644 docs/img/sponsors/3-gizmag.png create mode 100644 docs/img/sponsors/3-imt_computer_services.png create mode 100644 docs/img/sponsors/3-infinite_code.png create mode 100644 docs/img/sponsors/3-life_the_game.png create mode 100644 docs/img/sponsors/3-pkgfarm.png create mode 100644 docs/img/sponsors/3-providenz.png create mode 100644 docs/img/sponsors/3-shippo.png create mode 100644 docs/img/sponsors/3-thermondo-gmbh.png create mode 100644 docs/img/sponsors/3-tivix.png create mode 100644 docs/img/sponsors/3-triggered_messaging.png create mode 100644 docs/img/sponsors/3-wildfish.png diff --git a/docs/css/default.css b/docs/css/default.css index af6a9cc0..090d42a6 100644 --- a/docs/css/default.css +++ b/docs/css/default.css @@ -307,3 +307,34 @@ table { .side-nav { overflow-y: scroll; } + + +ul.sponsor.diamond li a { + float: left; + width: 600px; + height: 20px; + text-align: center; + margin: 10px 40px; + padding: 300px 0 0 0; + background-position: 0 50%; + background-size: 600px auto; + background-repeat: no-repeat; + font-size: 150%; +} + +ul.sponsor.platinum li a { + float: left; + width: 300px; + height: 20px; + text-align: center; + margin: 10px 40px; + padding: 300px 0 0 0; + background-position: 0 50%; + background-size: 280px auto; + background-repeat: no-repeat; + font-size: 150%; +} + +ul.sponsor { + list-style: none; +} diff --git a/docs/img/sponsors/0-eventbrite.png b/docs/img/sponsors/0-eventbrite.png new file mode 100644 index 00000000..6c739293 Binary files /dev/null and b/docs/img/sponsors/0-eventbrite.png differ diff --git a/docs/img/sponsors/1-cyan.png b/docs/img/sponsors/1-cyan.png new file mode 100644 index 00000000..d6b55b4c Binary files /dev/null and b/docs/img/sponsors/1-cyan.png differ diff --git a/docs/img/sponsors/1-divio.png b/docs/img/sponsors/1-divio.png new file mode 100644 index 00000000..8ced88f8 Binary files /dev/null and b/docs/img/sponsors/1-divio.png differ diff --git a/docs/img/sponsors/1-kuwaitnet.png b/docs/img/sponsors/1-kuwaitnet.png new file mode 100644 index 00000000..8b2d0550 Binary files /dev/null and b/docs/img/sponsors/1-kuwaitnet.png differ diff --git a/docs/img/sponsors/1-lulu.png b/docs/img/sponsors/1-lulu.png new file mode 100644 index 00000000..8a28bfa9 Binary files /dev/null and b/docs/img/sponsors/1-lulu.png differ diff --git a/docs/img/sponsors/1-potato.png b/docs/img/sponsors/1-potato.png new file mode 100644 index 00000000..ad38abdd Binary files /dev/null and b/docs/img/sponsors/1-potato.png differ diff --git a/docs/img/sponsors/1-purplebit.png b/docs/img/sponsors/1-purplebit.png new file mode 100644 index 00000000..0df63bf6 Binary files /dev/null and b/docs/img/sponsors/1-purplebit.png differ diff --git a/docs/img/sponsors/1-runscope.png b/docs/img/sponsors/1-runscope.png new file mode 100644 index 00000000..d80a4b85 Binary files /dev/null and b/docs/img/sponsors/1-runscope.png differ diff --git a/docs/img/sponsors/1-simple-energy.png b/docs/img/sponsors/1-simple-energy.png new file mode 100644 index 00000000..f59f7374 Binary files /dev/null and b/docs/img/sponsors/1-simple-energy.png differ diff --git a/docs/img/sponsors/1-vokal_interactive.png b/docs/img/sponsors/1-vokal_interactive.png new file mode 100644 index 00000000..f7811ecd Binary files /dev/null and b/docs/img/sponsors/1-vokal_interactive.png differ diff --git a/docs/img/sponsors/1-wiredrive.png b/docs/img/sponsors/1-wiredrive.png new file mode 100644 index 00000000..c9befefe Binary files /dev/null and b/docs/img/sponsors/1-wiredrive.png differ diff --git a/docs/img/sponsors/2-byte.png b/docs/img/sponsors/2-byte.png new file mode 100644 index 00000000..2c3777b5 Binary files /dev/null and b/docs/img/sponsors/2-byte.png differ diff --git a/docs/img/sponsors/2-crate.png b/docs/img/sponsors/2-crate.png new file mode 100644 index 00000000..6ef6b5da Binary files /dev/null and b/docs/img/sponsors/2-crate.png differ diff --git a/docs/img/sponsors/2-heroku.png b/docs/img/sponsors/2-heroku.png new file mode 100644 index 00000000..22447659 Binary files /dev/null and b/docs/img/sponsors/2-heroku.png differ diff --git a/docs/img/sponsors/2-hipflask.png b/docs/img/sponsors/2-hipflask.png new file mode 100644 index 00000000..c74735c3 Binary files /dev/null and b/docs/img/sponsors/2-hipflask.png differ diff --git a/docs/img/sponsors/2-hipo.png b/docs/img/sponsors/2-hipo.png new file mode 100644 index 00000000..2b854c6d Binary files /dev/null and b/docs/img/sponsors/2-hipo.png differ diff --git a/docs/img/sponsors/2-koordinates.png b/docs/img/sponsors/2-koordinates.png new file mode 100644 index 00000000..f38601b3 Binary files /dev/null and b/docs/img/sponsors/2-koordinates.png differ diff --git a/docs/img/sponsors/2-laterpay.png b/docs/img/sponsors/2-laterpay.png new file mode 100644 index 00000000..75eb97d3 Binary files /dev/null and b/docs/img/sponsors/2-laterpay.png differ diff --git a/docs/img/sponsors/2-lightning_kite.png b/docs/img/sponsors/2-lightning_kite.png new file mode 100644 index 00000000..ffdced04 Binary files /dev/null and b/docs/img/sponsors/2-lightning_kite.png differ diff --git a/docs/img/sponsors/2-mirus_research.png b/docs/img/sponsors/2-mirus_research.png new file mode 100644 index 00000000..b1544070 Binary files /dev/null and b/docs/img/sponsors/2-mirus_research.png differ diff --git a/docs/img/sponsors/2-opbeat.png b/docs/img/sponsors/2-opbeat.png new file mode 100644 index 00000000..c71a5241 Binary files /dev/null and b/docs/img/sponsors/2-opbeat.png differ diff --git a/docs/img/sponsors/2-schuberg_philis.png b/docs/img/sponsors/2-schuberg_philis.png new file mode 100644 index 00000000..fd9282ee Binary files /dev/null and b/docs/img/sponsors/2-schuberg_philis.png differ diff --git a/docs/img/sponsors/2-vinta.png b/docs/img/sponsors/2-vinta.png new file mode 100644 index 00000000..7c67f6ca Binary files /dev/null and b/docs/img/sponsors/2-vinta.png differ diff --git a/docs/img/sponsors/3-blimp.png b/docs/img/sponsors/3-blimp.png new file mode 100644 index 00000000..494bf792 Binary files /dev/null and b/docs/img/sponsors/3-blimp.png differ diff --git a/docs/img/sponsors/3-gizmag.png b/docs/img/sponsors/3-gizmag.png new file mode 100644 index 00000000..a8d41bd0 Binary files /dev/null and b/docs/img/sponsors/3-gizmag.png differ diff --git a/docs/img/sponsors/3-imt_computer_services.png b/docs/img/sponsors/3-imt_computer_services.png new file mode 100644 index 00000000..00643c97 Binary files /dev/null and b/docs/img/sponsors/3-imt_computer_services.png differ diff --git a/docs/img/sponsors/3-infinite_code.png b/docs/img/sponsors/3-infinite_code.png new file mode 100644 index 00000000..7a8fdcf1 Binary files /dev/null and b/docs/img/sponsors/3-infinite_code.png differ diff --git a/docs/img/sponsors/3-life_the_game.png b/docs/img/sponsors/3-life_the_game.png new file mode 100644 index 00000000..9292685e Binary files /dev/null and b/docs/img/sponsors/3-life_the_game.png differ diff --git a/docs/img/sponsors/3-pkgfarm.png b/docs/img/sponsors/3-pkgfarm.png new file mode 100644 index 00000000..9224cc2e Binary files /dev/null and b/docs/img/sponsors/3-pkgfarm.png differ diff --git a/docs/img/sponsors/3-providenz.png b/docs/img/sponsors/3-providenz.png new file mode 100644 index 00000000..55d9c992 Binary files /dev/null and b/docs/img/sponsors/3-providenz.png differ diff --git a/docs/img/sponsors/3-shippo.png b/docs/img/sponsors/3-shippo.png new file mode 100644 index 00000000..4f5ae133 Binary files /dev/null and b/docs/img/sponsors/3-shippo.png differ diff --git a/docs/img/sponsors/3-thermondo-gmbh.png b/docs/img/sponsors/3-thermondo-gmbh.png new file mode 100644 index 00000000..fe8691c8 Binary files /dev/null and b/docs/img/sponsors/3-thermondo-gmbh.png differ diff --git a/docs/img/sponsors/3-tivix.png b/docs/img/sponsors/3-tivix.png new file mode 100644 index 00000000..90d20753 Binary files /dev/null and b/docs/img/sponsors/3-tivix.png differ diff --git a/docs/img/sponsors/3-triggered_messaging.png b/docs/img/sponsors/3-triggered_messaging.png new file mode 100644 index 00000000..4f8e5063 Binary files /dev/null and b/docs/img/sponsors/3-triggered_messaging.png differ diff --git a/docs/img/sponsors/3-wildfish.png b/docs/img/sponsors/3-wildfish.png new file mode 100644 index 00000000..fa13ea70 Binary files /dev/null and b/docs/img/sponsors/3-wildfish.png differ diff --git a/docs/topics/kickstarter-announcement.md b/docs/topics/kickstarter-announcement.md index 98cf12e3..5f5b848e 100644 --- a/docs/topics/kickstarter-announcement.md +++ b/docs/topics/kickstarter-announcement.md @@ -29,3 +29,32 @@ I can't wait to see where this takes us! Many thanks to everyone for your support so far, Tom Christie :) + +--- + +## Sponsors + +We've now blazed way past all our goals, with a staggering £30,000 (~$50,000), meaning I'll be in a position to work on the project significantly beyond what we'd originally planned for. I owe a huge debt of gratitude to all the wonderful companies and individuals who have been backing the project so generously, and making this possible. + +--- + +### Platinum sponsors + +Our platinum sponsors have each made a hugely substantial contribution to the future development of Django REST framework, and I simply can't thank them enough. + + + + -- cgit v1.2.3 From c0f002b09d07275d8dbba7266d1180623b78f6a5 Mon Sep 17 00:00:00 2001 From: Kevin London Date: Thu, 31 Jul 2014 12:41:15 -0700 Subject: Updated Permissions doc link to Django docs The previous link went to version 1 docs so it was a dead link.--- docs/api-guide/permissions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api-guide/permissions.md b/docs/api-guide/permissions.md index c44b22de..38ae3d0a 100644 --- a/docs/api-guide/permissions.md +++ b/docs/api-guide/permissions.md @@ -244,7 +244,7 @@ The [REST Condition][rest-condition] package is another extension for building c [authentication]: authentication.md [throttling]: throttling.md [filtering]: filtering.md -[contribauth]: https://docs.djangoproject.com/en/1.0/topics/auth/#permissions +[contribauth]: https://docs.djangoproject.com/en/dev/topics/auth/customizing/#custom-permissions [objectpermissions]: https://docs.djangoproject.com/en/dev/topics/auth/customizing/#handling-object-permissions [guardian]: https://github.com/lukaszb/django-guardian [get_objects_for_user]: http://pythonhosted.org/django-guardian/api/guardian.shortcuts.html#get-objects-for-user -- cgit v1.2.3 From 6677374e9b7ec0d4379042cc3e2ee601bf95a9ab Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Thu, 31 Jul 2014 22:33:45 +0100 Subject: Kickstarter sponsors --- docs/css/default.css | 46 ++++++++++++++++++- docs/img/sponsors/2-cryptico.png | Bin 0 -> 9970 bytes docs/img/sponsors/2-django.png | Bin 0 -> 5055 bytes docs/img/sponsors/2-galileo_press.png | Bin 0 -> 11451 bytes docs/img/sponsors/2-security_compass.png | Bin 0 -> 4107 bytes docs/img/sponsors/2-sirono.png | Bin 0 -> 4941 bytes docs/img/sponsors/3-brightloop.png | Bin 0 -> 6864 bytes docs/topics/kickstarter-announcement.md | 75 +++++++++++++++++++++++++++++++ 8 files changed, 119 insertions(+), 2 deletions(-) create mode 100644 docs/img/sponsors/2-cryptico.png create mode 100644 docs/img/sponsors/2-django.png create mode 100644 docs/img/sponsors/2-galileo_press.png create mode 100644 docs/img/sponsors/2-security_compass.png create mode 100644 docs/img/sponsors/2-sirono.png create mode 100644 docs/img/sponsors/3-brightloop.png diff --git a/docs/css/default.css b/docs/css/default.css index 090d42a6..7f3acfed 100644 --- a/docs/css/default.css +++ b/docs/css/default.css @@ -314,12 +314,27 @@ ul.sponsor.diamond li a { width: 600px; height: 20px; text-align: center; - margin: 10px 40px; + margin: 10px 70px; padding: 300px 0 0 0; background-position: 0 50%; background-size: 600px auto; background-repeat: no-repeat; - font-size: 150%; + font-size: 200%; +} + +@media (max-width: 1000px) { + ul.sponsor.diamond li a { + float: left; + width: 300px; + height: 20px; + text-align: center; + margin: 10px 40px; + padding: 300px 0 0 0; + background-position: 0 50%; + background-size: 280px auto; + background-repeat: no-repeat; + font-size: 150%; + } } ul.sponsor.platinum li a { @@ -335,6 +350,33 @@ ul.sponsor.platinum li a { font-size: 150%; } +ul.sponsor.gold li a { + float: left; + width: 130px; + height: 20px; + text-align: center; + margin: 10px 30px; + padding: 150px 0 0 0; + background-position: 0 50%; + background-size: 130px auto; + background-repeat: no-repeat; + font-size: 120%; +} + +ul.sponsor.silver li a { + float: left; + width: 130px; + height: 20px; + text-align: center; + margin: 10px 30px; + padding: 150px 0 0 0; + background-position: 0 50%; + background-size: 130px auto; + background-repeat: no-repeat; + font-size: 120%; +} + ul.sponsor { list-style: none; + display: block; } diff --git a/docs/img/sponsors/2-cryptico.png b/docs/img/sponsors/2-cryptico.png new file mode 100644 index 00000000..2d86afe8 Binary files /dev/null and b/docs/img/sponsors/2-cryptico.png differ diff --git a/docs/img/sponsors/2-django.png b/docs/img/sponsors/2-django.png new file mode 100644 index 00000000..c89e19cb Binary files /dev/null and b/docs/img/sponsors/2-django.png differ diff --git a/docs/img/sponsors/2-galileo_press.png b/docs/img/sponsors/2-galileo_press.png new file mode 100644 index 00000000..f77e6c0a Binary files /dev/null and b/docs/img/sponsors/2-galileo_press.png differ diff --git a/docs/img/sponsors/2-security_compass.png b/docs/img/sponsors/2-security_compass.png new file mode 100644 index 00000000..abd63dbe Binary files /dev/null and b/docs/img/sponsors/2-security_compass.png differ diff --git a/docs/img/sponsors/2-sirono.png b/docs/img/sponsors/2-sirono.png new file mode 100644 index 00000000..0a243001 Binary files /dev/null and b/docs/img/sponsors/2-sirono.png differ diff --git a/docs/img/sponsors/3-brightloop.png b/docs/img/sponsors/3-brightloop.png new file mode 100644 index 00000000..8d5e85a6 Binary files /dev/null and b/docs/img/sponsors/3-brightloop.png differ diff --git a/docs/topics/kickstarter-announcement.md b/docs/topics/kickstarter-announcement.md index 5f5b848e..24c609fa 100644 --- a/docs/topics/kickstarter-announcement.md +++ b/docs/topics/kickstarter-announcement.md @@ -58,3 +58,78 @@ Our platinum sponsors have each made a hugely substantial contribution to the fu
  • Purple Bit
  • KuwaitNET
  • + +
    + +--- + +### Gold sponsors + +Our gold sponsors include companies large and small. Many thanks for their significant funding of the project and their commitment to sustainable open-source development. + + + + + +
    + +--- + +### Silver sponsors + +The serious financial contribution that our silver sponsors have made is very much appreciated. I'd like to say a particular thank you to individuals who have choosen to privately support the project at this level. + + + +
    + +**Individual contributions**: Paul Hallet, Paul Whipp Consulting, Jannis Leidel. + -- cgit v1.2.3 From ebcc78d96cf6f4cd6e464cd6b8eccd83305900c2 Mon Sep 17 00:00:00 2001 From: Anler Hp Date: Fri, 1 Aug 2014 10:20:10 +0200 Subject: Leave status responsibility to parent class Django's `HttpResponse` class checks for the `status` param when it's initialized, if it's `None` it uses the class attribute `status_code` and thanks to that we can do things like: ``` class BadRequest(HttpResponse): status_code = 400 ``` Now, that doesn't work when inheriting from rest-framework's `Response`: ``` class BadRequest(rest_framework.response.Response): status_code = 400 # Bad, it's always ignored ``` Because a default status of `200` is being specified in `rest_framework.response.Response`. I think is more Django-friendly to just leave that status default value to `None` and leave the responsibility of choosing its value to the parent class: `HttpResponse`. --- rest_framework/response.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest_framework/response.py b/rest_framework/response.py index 5c02ea50..25b78524 100644 --- a/rest_framework/response.py +++ b/rest_framework/response.py @@ -20,7 +20,7 @@ class Response(SimpleTemplateResponse): if django.VERSION >= (1, 4): rendering_attrs = SimpleTemplateResponse.rendering_attrs + ['_closable_objects'] - def __init__(self, data=None, status=200, + def __init__(self, data=None, status=None, template_name=None, headers=None, exception=False, content_type=None): """ -- cgit v1.2.3 From f87aadb3ced996f54d26d3505ec3df76fcba23df Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Fri, 1 Aug 2014 11:35:48 +0100 Subject: Latest sponsor updates --- docs/img/sponsors/2-vinta.png | Bin 9918 -> 6844 bytes docs/img/sponsors/3-beefarm.png | Bin 0 -> 13066 bytes docs/img/sponsors/3-fluxility.png | Bin 0 -> 10064 bytes docs/img/sponsors/3-nephila.png | Bin 0 -> 5842 bytes docs/img/sponsors/3-tivix.png | Bin 4091 -> 3552 bytes docs/img/sponsors/3-trackmaven.png | Bin 0 -> 28609 bytes docs/topics/kickstarter-announcement.md | 12 +++++++++--- 7 files changed, 9 insertions(+), 3 deletions(-) create mode 100644 docs/img/sponsors/3-beefarm.png create mode 100644 docs/img/sponsors/3-fluxility.png create mode 100644 docs/img/sponsors/3-nephila.png create mode 100644 docs/img/sponsors/3-trackmaven.png diff --git a/docs/img/sponsors/2-vinta.png b/docs/img/sponsors/2-vinta.png index 7c67f6ca..4f4d75bc 100644 Binary files a/docs/img/sponsors/2-vinta.png and b/docs/img/sponsors/2-vinta.png differ diff --git a/docs/img/sponsors/3-beefarm.png b/docs/img/sponsors/3-beefarm.png new file mode 100644 index 00000000..3348df42 Binary files /dev/null and b/docs/img/sponsors/3-beefarm.png differ diff --git a/docs/img/sponsors/3-fluxility.png b/docs/img/sponsors/3-fluxility.png new file mode 100644 index 00000000..eacd7da9 Binary files /dev/null and b/docs/img/sponsors/3-fluxility.png differ diff --git a/docs/img/sponsors/3-nephila.png b/docs/img/sponsors/3-nephila.png new file mode 100644 index 00000000..12fa46d0 Binary files /dev/null and b/docs/img/sponsors/3-nephila.png differ diff --git a/docs/img/sponsors/3-tivix.png b/docs/img/sponsors/3-tivix.png index 90d20753..bc2616a6 100644 Binary files a/docs/img/sponsors/3-tivix.png and b/docs/img/sponsors/3-tivix.png differ diff --git a/docs/img/sponsors/3-trackmaven.png b/docs/img/sponsors/3-trackmaven.png new file mode 100644 index 00000000..8d613696 Binary files /dev/null and b/docs/img/sponsors/3-trackmaven.png differ diff --git a/docs/topics/kickstarter-announcement.md b/docs/topics/kickstarter-announcement.md index 24c609fa..00d4778f 100644 --- a/docs/topics/kickstarter-announcement.md +++ b/docs/topics/kickstarter-announcement.md @@ -119,17 +119,23 @@ The serious financial contribution that our silver sponsors have made is very mu
  • Bright Loop
  • - +
  • beefarm.ru
  • -
  • Infinate Code
  • +
  • Infinite Code
  • PkgFarm
  • Life. The Game.
  • Blimp
  • + +
  • Fluxility
  • +
  • TrackMaven
  • +
  • Nephila
  • + +
    -**Individual contributions**: Paul Hallet, Paul Whipp Consulting, Jannis Leidel. +**Individual contributions**: Paul Hallet, Paul Whipp, Jannis Leidel, Johannes Spielmann, Chris Heisel. -- cgit v1.2.3 From 27af7a3f4f9870c85d44fde37b041d51d3611473 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Fri, 1 Aug 2014 11:36:33 +0100 Subject: Latest sponsor updates --- docs/img/sponsors/3-trackmaven.png | Bin 28609 -> 5331 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/img/sponsors/3-trackmaven.png b/docs/img/sponsors/3-trackmaven.png index 8d613696..3880e370 100644 Binary files a/docs/img/sponsors/3-trackmaven.png and b/docs/img/sponsors/3-trackmaven.png differ -- cgit v1.2.3 From 5377bda9420b5806cfcfceddcfdfbedf5629f6ce Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Fri, 1 Aug 2014 13:42:51 +0100 Subject: Fix LaterPay link --- docs/topics/kickstarter-announcement.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/topics/kickstarter-announcement.md b/docs/topics/kickstarter-announcement.md index 00d4778f..93f670aa 100644 --- a/docs/topics/kickstarter-announcement.md +++ b/docs/topics/kickstarter-announcement.md @@ -68,7 +68,7 @@ Our platinum sponsors have each made a hugely substantial contribution to the fu Our gold sponsors include companies large and small. Many thanks for their significant funding of the project and their commitment to sustainable open-source development.
    -- cgit v1.2.3 From 62d0d4e5d2f203d2c1694af363bce88cc1a5d483 Mon Sep 17 00:00:00 2001 From: nimiq Date: Wed, 6 Aug 2014 12:45:58 +0200 Subject: Fix style for some text --- docs/tutorial/5-relationships-and-hyperlinked-apis.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorial/5-relationships-and-hyperlinked-apis.md b/docs/tutorial/5-relationships-and-hyperlinked-apis.md index 2cf44bf9..aef92d08 100644 --- a/docs/tutorial/5-relationships-and-hyperlinked-apis.md +++ b/docs/tutorial/5-relationships-and-hyperlinked-apis.md @@ -29,7 +29,7 @@ Unlike all our other API endpoints, we don't want to use JSON, but instead just The other thing we need to consider when creating the code highlight view is that there's no existing concrete generic view that we can use. We're not returning an object instance, but instead a property of an object instance. -Instead of using a concrete generic view, we'll use the base class for representing instances, and create our own `.get()` method. In your snippets.views add: +Instead of using a concrete generic view, we'll use the base class for representing instances, and create our own `.get()` method. In your `snippets.views` add: from rest_framework import renderers from rest_framework.response import Response -- cgit v1.2.3 From 3217842346cebda578e9398b89fe60fed7d1b2d8 Mon Sep 17 00:00:00 2001 From: Rob Terhaar Date: Wed, 6 Aug 2014 18:55:08 -0400 Subject: minor doc fix, @api_view() needs an iterable --- docs/api-guide/throttling.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api-guide/throttling.md b/docs/api-guide/throttling.md index b7c320f0..92f4c22b 100644 --- a/docs/api-guide/throttling.md +++ b/docs/api-guide/throttling.md @@ -58,7 +58,7 @@ using the `APIView` class based views. Or, if you're using the `@api_view` decorator with function based views. - @api_view('GET') + @api_view(['GET']) @throttle_classes([UserRateThrottle]) def example_view(request, format=None): content = { -- cgit v1.2.3 From 617745eca027dc17c37718a67f82700caef5be3a Mon Sep 17 00:00:00 2001 From: Kevin London Date: Wed, 6 Aug 2014 16:26:56 -0700 Subject: Update description of OrderingFilter I added a brief description of how you could specify a different query parameter for the OrderingFilter.--- rest_framework/filters.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rest_framework/filters.py b/rest_framework/filters.py index 96d15eb9..c3b846ae 100644 --- a/rest_framework/filters.py +++ b/rest_framework/filters.py @@ -116,6 +116,10 @@ class OrderingFilter(BaseFilterBackend): def get_ordering(self, request): """ Ordering is set by a comma delimited ?ordering=... query parameter. + + The `ordering` query parameter can be overridden by setting + the `ordering_param` value on the OrderingFilter or by + specifying an `ORDERING_PARAM` value in the API settings. """ params = request.QUERY_PARAMS.get(self.ordering_param) if params: -- cgit v1.2.3 From aac864a55f8aec80f35d43052b67c2558814df16 Mon Sep 17 00:00:00 2001 From: Kevin London Date: Thu, 7 Aug 2014 11:02:48 -0700 Subject: Updated documentation for urls.py I made a small change in the order of the documentation for urls.py. I feel it helps make it clear which lines you should add to the root settings.--- rest_framework/urls.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rest_framework/urls.py b/rest_framework/urls.py index 9c4719f1..5d70f899 100644 --- a/rest_framework/urls.py +++ b/rest_framework/urls.py @@ -2,15 +2,15 @@ Login and logout views for the browsable API. Add these to your root URLconf if you're using the browsable API and -your API requires authentication. - -The urls must be namespaced as 'rest_framework', and you should make sure -your authentication settings include `SessionAuthentication`. +your API requires authentication: urlpatterns = patterns('', ... url(r'^auth', include('rest_framework.urls', namespace='rest_framework')) ) + +The urls must be namespaced as 'rest_framework', and you should make sure +your authentication settings include `SessionAuthentication`. """ from __future__ import unicode_literals from rest_framework.compat import patterns, url -- cgit v1.2.3 From bc03d2b553bc2c5bc341bb6fd43f8fe382e3cd41 Mon Sep 17 00:00:00 2001 From: Kevin London Date: Thu, 7 Aug 2014 16:32:40 -0700 Subject: Updated links to Bootstrap components The previous links landed on the the main page and no longer directly linked to specific areas.--- docs/topics/browsable-api.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/topics/browsable-api.md b/docs/topics/browsable-api.md index e32db695..96cdabe6 100644 --- a/docs/topics/browsable-api.md +++ b/docs/topics/browsable-api.md @@ -167,10 +167,10 @@ You can now add the `autocomplete_light.ChoiceWidget` widget to the serializer f [bootstrap]: http://getbootstrap.com [cerulean]: ../img/cerulean.png [slate]: ../img/slate.png -[bcustomize]: http://twitter.github.com/bootstrap/customize.html#variables +[bcustomize]: http://getbootstrap.com/2.3.2/customize.html [bswatch]: http://bootswatch.com/ -[bcomponents]: http://twitter.github.com/bootstrap/components.html -[bcomponentsnav]: http://twitter.github.com/bootstrap/components.html#navbar +[bcomponents]: http://getbootstrap.com/2.3.2/components.html +[bcomponentsnav]: http://getbootstrap.com/2.3.2/components.html#navbar [autocomplete-packages]: https://www.djangopackages.com/grids/g/auto-complete/ [django-autocomplete-light]: https://github.com/yourlabs/django-autocomplete-light [django-autocomplete-light-install]: http://django-autocomplete-light.readthedocs.org/en/latest/#install -- cgit v1.2.3 From 5eb901cd2a7dc2e33034f49e076bf7af7656655a Mon Sep 17 00:00:00 2001 From: Federico Capoano Date: Fri, 8 Aug 2014 14:25:02 +0200 Subject: docs: added reference to DRF-gis in fields added django-rest-framework-gis to third party packages section in /docs/api-guide/fields.md--- docs/api-guide/fields.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/api-guide/fields.md b/docs/api-guide/fields.md index 813fc381..dd279541 100644 --- a/docs/api-guide/fields.md +++ b/docs/api-guide/fields.md @@ -361,6 +361,9 @@ The [drf-compound-fields][drf-compound-fields] package provides "compound" seria The [drf-extra-fields][drf-extra-fields] package provides extra serializer fields for REST framework, including `Base64ImageField` and `PointField` classes. +## django-rest-framework-gis + +The [django-rest-framework-gis][django-rest-framework-gis] package provides geographic addons for django rest framework like a `GeometryField` field and a GeoJSON serializer. [cite]: https://docs.djangoproject.com/en/dev/ref/forms/api/#django.forms.Form.cleaned_data @@ -370,3 +373,4 @@ The [drf-extra-fields][drf-extra-fields] package provides extra serializer field [iso8601]: http://www.w3.org/TR/NOTE-datetime [drf-compound-fields]: http://drf-compound-fields.readthedocs.org [drf-extra-fields]: https://github.com/Hipo/drf-extra-fields +[django-rest-framework-gis]: https://github.com/djangonauts/django-rest-framework-gis -- cgit v1.2.3 From c462a43a872b45d27def08a3d17799b930950860 Mon Sep 17 00:00:00 2001 From: Federico Capoano Date: Fri, 8 Aug 2014 14:39:56 +0200 Subject: docs: added reference to gis serializer added reference to GeoFeatureModelSerializer of django-rest-framework-gis--- docs/api-guide/serializers.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/api-guide/serializers.md b/docs/api-guide/serializers.md index 72568e53..29b7851b 100644 --- a/docs/api-guide/serializers.md +++ b/docs/api-guide/serializers.md @@ -590,6 +590,11 @@ The following third party packages are also available. The [django-rest-framework-mongoengine][mongoengine] package provides a `MongoEngineModelSerializer` serializer class that supports using MongoDB as the storage layer for Django REST framework. +## GeoFeatureModelSerializer + +The [django-rest-framework-gis][django-rest-framework-gis] package provides a `GeoFeatureModelSerializer` serializer class that supports GeoJSON both for read and write operations. + [cite]: https://groups.google.com/d/topic/django-users/sVFaOfQi4wY/discussion [relations]: relations.md [mongoengine]: https://github.com/umutbozkurt/django-rest-framework-mongoengine +[django-rest-framework-gis]: https://github.com/djangonauts/django-rest-framework-gis -- cgit v1.2.3 From 09c53bbac9205b46bafd77e456b495c63c9d46ef Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Mon, 11 Aug 2014 16:20:27 +0100 Subject: Refactor JSONRenderer slightly for easier overriding --- rest_framework/renderers.py | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/rest_framework/renderers.py b/rest_framework/renderers.py index 484961ad..7048d87d 100644 --- a/rest_framework/renderers.py +++ b/rest_framework/renderers.py @@ -54,32 +54,37 @@ class JSONRenderer(BaseRenderer): format = 'json' encoder_class = encoders.JSONEncoder ensure_ascii = True - charset = None - # JSON is a binary encoding, that can be encoded as utf-8, utf-16 or utf-32. + + # We don't set a charset because JSON is a binary encoding, + # that can be encoded as utf-8, utf-16 or utf-32. # See: http://www.ietf.org/rfc/rfc4627.txt # Also: http://lucumr.pocoo.org/2013/7/19/application-mimetypes-and-encodings/ + charset = None + + def get_indent(self, accepted_media_type, renderer_context): + if accepted_media_type: + # If the media type looks like 'application/json; indent=4', + # then pretty print the result. + base_media_type, params = parse_header(accepted_media_type.encode('ascii')) + try: + return max(min(int(params['indent']), 8), 0) + except (KeyError, ValueError, TypeError): + pass + + # If 'indent' is provided in the context, then pretty print the result. + # E.g. If we're being called by the BrowsableAPIRenderer. + return renderer_context.get('indent', None) + def render(self, data, accepted_media_type=None, renderer_context=None): """ - Render `data` into JSON. + Render `data` into JSON, returning a bytestring. """ if data is None: return bytes() - # If 'indent' is provided in the context, then pretty print the result. - # E.g. If we're being called by the BrowsableAPIRenderer. renderer_context = renderer_context or {} - indent = renderer_context.get('indent', None) - - if accepted_media_type: - # If the media type looks like 'application/json; indent=4', - # then pretty print the result. - base_media_type, params = parse_header(accepted_media_type.encode('ascii')) - indent = params.get('indent', indent) - try: - indent = max(min(int(indent), 8), 0) - except (ValueError, TypeError): - indent = None + indent = self.get_indent(accepted_media_type, renderer_context) ret = json.dumps(data, cls=self.encoder_class, indent=indent, ensure_ascii=self.ensure_ascii) -- cgit v1.2.3 From f46b55b75f284a2fa3b1c79300c282f6cbdfc1ee Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Tue, 12 Aug 2014 13:44:00 +0100 Subject: Added OpenEye as a silver sponsor --- docs/img/sponsors/3-openeye.png | Bin 0 -> 14155 bytes docs/topics/kickstarter-announcement.md | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 docs/img/sponsors/3-openeye.png diff --git a/docs/img/sponsors/3-openeye.png b/docs/img/sponsors/3-openeye.png new file mode 100644 index 00000000..573140ed Binary files /dev/null and b/docs/img/sponsors/3-openeye.png differ diff --git a/docs/topics/kickstarter-announcement.md b/docs/topics/kickstarter-announcement.md index 1ffa0ed3..13215337 100644 --- a/docs/topics/kickstarter-announcement.md +++ b/docs/topics/kickstarter-announcement.md @@ -134,7 +134,7 @@ The serious financial contribution that our silver sponsors have made is very mu
  • Nephila
  • Aditium
  • - +
  • OpenEye Scientific Software
  • -- cgit v1.2.3 From 7551db23caddbe7a0e01d01fb314daeaf2a61257 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Tue, 12 Aug 2014 13:47:34 +0100 Subject: Added Rob Spectre --- docs/topics/kickstarter-announcement.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/topics/kickstarter-announcement.md b/docs/topics/kickstarter-announcement.md index 13215337..ab12c4cf 100644 --- a/docs/topics/kickstarter-announcement.md +++ b/docs/topics/kickstarter-announcement.md @@ -139,5 +139,5 @@ The serious financial contribution that our silver sponsors have made is very mu
    -**Individual contributions**: Paul Hallet, Paul Whipp, Jannis Leidel, Johannes Spielmann, Chris Heisel, Marwan Alsabbagh. +**Individual contributions**: Paul Hallet, Paul Whipp, Jannis Leidel, Johannes Spielmann, Rob Spectre, Chris Heisel, Marwan Alsabbagh. -- cgit v1.2.3 From c716f35825b708a01c4c1fab07860634cc0e4b9a Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Tue, 12 Aug 2014 14:57:27 +0100 Subject: Added Cantemo --- docs/img/sponsors/3-cantemo.gif | Bin 0 -> 4526 bytes docs/img/sponsors/3-teonite.png | Bin 0 -> 7882 bytes docs/topics/kickstarter-announcement.md | 3 ++- 3 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 docs/img/sponsors/3-cantemo.gif create mode 100644 docs/img/sponsors/3-teonite.png diff --git a/docs/img/sponsors/3-cantemo.gif b/docs/img/sponsors/3-cantemo.gif new file mode 100644 index 00000000..17b1e8d0 Binary files /dev/null and b/docs/img/sponsors/3-cantemo.gif differ diff --git a/docs/img/sponsors/3-teonite.png b/docs/img/sponsors/3-teonite.png new file mode 100644 index 00000000..0c098478 Binary files /dev/null and b/docs/img/sponsors/3-teonite.png differ diff --git a/docs/topics/kickstarter-announcement.md b/docs/topics/kickstarter-announcement.md index ab12c4cf..370d950d 100644 --- a/docs/topics/kickstarter-announcement.md +++ b/docs/topics/kickstarter-announcement.md @@ -121,7 +121,6 @@ The serious financial contribution that our silver sponsors have made is very mu
  • ABA Systems
  • beefarm.ru
  • Vzzual.com
  • -
  • Infinite Code
  • @@ -130,11 +129,13 @@ The serious financial contribution that our silver sponsors have made is very mu
  • Blimp
  • Pathwright
  • Fluxility
  • +
  • Teonite
  • TrackMaven
  • Nephila
  • Aditium
  • OpenEye Scientific Software
  • +
  • Cantemo
  • -- cgit v1.2.3 From 5d674927b8d98d6c76a97e06496f2033108689eb Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Tue, 12 Aug 2014 14:59:17 +0100 Subject: Minor docs style change --- docs/topics/kickstarter-announcement.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/topics/kickstarter-announcement.md b/docs/topics/kickstarter-announcement.md index 370d950d..7726cb83 100644 --- a/docs/topics/kickstarter-announcement.md +++ b/docs/topics/kickstarter-announcement.md @@ -138,7 +138,7 @@ The serious financial contribution that our silver sponsors have made is very mu
  • Cantemo
  • -
    +
    **Individual contributions**: Paul Hallet, Paul Whipp, Jannis Leidel, Johannes Spielmann, Rob Spectre, Chris Heisel, Marwan Alsabbagh. -- cgit v1.2.3 From c52075f392420356c471860dc07f9371002efe39 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Wed, 13 Aug 2014 14:02:09 +0100 Subject: Latest sponsor update --- docs/img/sponsors/2-nexthub.png | Bin 0 -> 2562 bytes docs/img/sponsors/3-crosswordtracker.png | Bin 0 -> 6715 bytes docs/img/sponsors/3-phurba.png | Bin 0 -> 3064 bytes docs/img/sponsors/3-transcode.png | Bin 0 -> 8615 bytes docs/topics/kickstarter-announcement.md | 6 ++++-- 5 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 docs/img/sponsors/2-nexthub.png create mode 100644 docs/img/sponsors/3-crosswordtracker.png create mode 100644 docs/img/sponsors/3-phurba.png create mode 100644 docs/img/sponsors/3-transcode.png diff --git a/docs/img/sponsors/2-nexthub.png b/docs/img/sponsors/2-nexthub.png new file mode 100644 index 00000000..9bf76e0b Binary files /dev/null and b/docs/img/sponsors/2-nexthub.png differ diff --git a/docs/img/sponsors/3-crosswordtracker.png b/docs/img/sponsors/3-crosswordtracker.png new file mode 100644 index 00000000..f72362ea Binary files /dev/null and b/docs/img/sponsors/3-crosswordtracker.png differ diff --git a/docs/img/sponsors/3-phurba.png b/docs/img/sponsors/3-phurba.png new file mode 100644 index 00000000..657d872c Binary files /dev/null and b/docs/img/sponsors/3-phurba.png differ diff --git a/docs/img/sponsors/3-transcode.png b/docs/img/sponsors/3-transcode.png new file mode 100644 index 00000000..1faad69d Binary files /dev/null and b/docs/img/sponsors/3-transcode.png differ diff --git a/docs/topics/kickstarter-announcement.md b/docs/topics/kickstarter-announcement.md index 7726cb83..aca6b327 100644 --- a/docs/topics/kickstarter-announcement.md +++ b/docs/topics/kickstarter-announcement.md @@ -90,6 +90,7 @@ Our gold sponsors include companies large and small. Many thanks for their signi
  • Hipflask
  • Crate
  • Cryptico Corp
  • +
  • NextHub
  • Envision Linux
  • @@ -110,7 +111,7 @@ The serious financial contribution that our silver sponsors have made is very mu
  • Providenz
  • alwaysdata.com
  • Triggered Messaging
  • - +
  • Transcode
  • Garfo
  • Shippo
  • @@ -123,7 +124,7 @@ The serious financial contribution that our silver sponsors have made is very mu
  • Vzzual.com
  • Infinite Code
  • - +
  • Crossword Tracker
  • PkgFarm
  • Life. The Game.
  • Blimp
  • @@ -131,6 +132,7 @@ The serious financial contribution that our silver sponsors have made is very mu
  • Fluxility
  • Teonite
  • TrackMaven
  • +
  • Phurba
  • Nephila
  • Aditium
  • -- cgit v1.2.3 From 34c1da3515dbf4e9a0d645ebf81cde6f61254e31 Mon Sep 17 00:00:00 2001 From: John Whitlock Date: Wed, 13 Aug 2014 15:31:25 -0500 Subject: ModelSerializer.restore_object - errors as list When a ValueError is raised in ModelSerializer.restore_object, the error is set to a one-element list, rather than a bare string. --- rest_framework/serializers.py | 2 +- rest_framework/tests/test_serializer.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index c2b414d7..43d339da 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -977,7 +977,7 @@ class ModelSerializer(Serializer): try: setattr(instance, key, val) except ValueError: - self._errors[key] = self.error_messages['required'] + self._errors[key] = [self.error_messages['required']] # Any relations that cannot be set until we've # saved the model get hidden away on these diff --git a/rest_framework/tests/test_serializer.py b/rest_framework/tests/test_serializer.py index 91248ce7..fb2eac0b 100644 --- a/rest_framework/tests/test_serializer.py +++ b/rest_framework/tests/test_serializer.py @@ -685,7 +685,7 @@ class ModelValidationTests(TestCase): photo_serializer = PhotoSerializer(instance=photo, data={'album': ''}, partial=True) self.assertFalse(photo_serializer.is_valid()) self.assertTrue('album' in photo_serializer.errors) - self.assertEqual(photo_serializer.errors['album'], photo_serializer.error_messages['required']) + self.assertEqual(photo_serializer.errors['album'], [photo_serializer.error_messages['required']]) def test_foreign_key_with_partial(self): """ -- cgit v1.2.3 From bdb884aceb57d8d4e17a9176d557b6ff879f5a02 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Thu, 14 Aug 2014 16:57:21 +0100 Subject: Latest sponsor update --- docs/img/sponsors/3-makespace.png | Bin 0 -> 8420 bytes docs/topics/kickstarter-announcement.md | 1 + 2 files changed, 1 insertion(+) create mode 100644 docs/img/sponsors/3-makespace.png diff --git a/docs/img/sponsors/3-makespace.png b/docs/img/sponsors/3-makespace.png new file mode 100644 index 00000000..80b79361 Binary files /dev/null and b/docs/img/sponsors/3-makespace.png differ diff --git a/docs/topics/kickstarter-announcement.md b/docs/topics/kickstarter-announcement.md index aca6b327..74b19deb 100644 --- a/docs/topics/kickstarter-announcement.md +++ b/docs/topics/kickstarter-announcement.md @@ -138,6 +138,7 @@ The serious financial contribution that our silver sponsors have made is very mu
  • Aditium
  • OpenEye Scientific Software
  • Cantemo
  • +
  • MakeSpace
  • -- cgit v1.2.3 From 63d5634c660d21638114ccb35b0b756aae47b713 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Thu, 14 Aug 2014 16:59:40 +0100 Subject: Minor sponsor correction --- docs/topics/kickstarter-announcement.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/topics/kickstarter-announcement.md b/docs/topics/kickstarter-announcement.md index 74b19deb..cb8a1307 100644 --- a/docs/topics/kickstarter-announcement.md +++ b/docs/topics/kickstarter-announcement.md @@ -138,7 +138,7 @@ The serious financial contribution that our silver sponsors have made is very mu
  • Aditium
  • OpenEye Scientific Software
  • Cantemo
  • -
  • MakeSpace
  • +
  • MakeSpace
  • -- cgit v1.2.3 From bfd0b261dbcdab5993f83baefcd732d3d2d194e8 Mon Sep 17 00:00:00 2001 From: catherinedodge Date: Thu, 14 Aug 2014 13:39:21 -0400 Subject: Fixed small typo --- docs/topics/documenting-your-api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/topics/documenting-your-api.md b/docs/topics/documenting-your-api.md index 6291c924..e20f9712 100644 --- a/docs/topics/documenting-your-api.md +++ b/docs/topics/documenting-your-api.md @@ -95,7 +95,7 @@ You can modify the response behavior to `OPTIONS` requests by overriding the `me To be fully RESTful an API should present its available actions as hypermedia controls in the responses that it sends. -In this approach, rather than documenting the available API endpoints up front, the description instead concentrates on the *media types* that are used. The available actions take may be taken on any given URL are not strictly fixed, but are instead made available by the presence of link and form controls in the returned document. +In this approach, rather than documenting the available API endpoints up front, the description instead concentrates on the *media types* that are used. The available actions that may be taken on any given URL are not strictly fixed, but are instead made available by the presence of link and form controls in the returned document. To implement a hypermedia API you'll need to decide on an appropriate media type for the API, and implement a custom renderer and parser for that media type. The [REST, Hypermedia & HATEOAS][hypermedia-docs] section of the documentation includes pointers to background reading, as well as links to various hypermedia formats. -- cgit v1.2.3 From 4dd7b5f376be7d5f28ba8865cf4ede7ad553b8de Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Fri, 15 Aug 2014 12:05:19 +0100 Subject: Replace docs title. Easy is a sucky word choice. --- mkdocs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkdocs.py b/mkdocs.py index 529d2314..adeb6053 100755 --- a/mkdocs.py +++ b/mkdocs.py @@ -142,7 +142,7 @@ for (dirpath, dirnames, filenames) in os.walk(docs_dir): toc += template + '\n' if filename == 'index.md': - main_title = 'Django REST framework - APIs made easy' + main_title = 'Django REST framework - Web APIs for Django' else: main_title = main_title + ' - Django REST framework' -- cgit v1.2.3 From a5561954d79659ef987847fc361f83e6226fc885 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Fri, 15 Aug 2014 15:36:49 +0100 Subject: Latest sponsor updates --- docs/img/sponsors/3-ax_semantics.png | Bin 0 -> 11509 bytes docs/img/sponsors/3-ipushpull.png | Bin 0 -> 10089 bytes docs/img/sponsors/3-isl.png | Bin 0 -> 19203 bytes docs/topics/kickstarter-announcement.md | 24 +++++++++++++++++++++--- 4 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 docs/img/sponsors/3-ax_semantics.png create mode 100644 docs/img/sponsors/3-ipushpull.png create mode 100644 docs/img/sponsors/3-isl.png diff --git a/docs/img/sponsors/3-ax_semantics.png b/docs/img/sponsors/3-ax_semantics.png new file mode 100644 index 00000000..c072e028 Binary files /dev/null and b/docs/img/sponsors/3-ax_semantics.png differ diff --git a/docs/img/sponsors/3-ipushpull.png b/docs/img/sponsors/3-ipushpull.png new file mode 100644 index 00000000..e70b8bad Binary files /dev/null and b/docs/img/sponsors/3-ipushpull.png differ diff --git a/docs/img/sponsors/3-isl.png b/docs/img/sponsors/3-isl.png new file mode 100644 index 00000000..0bf0cf7c Binary files /dev/null and b/docs/img/sponsors/3-isl.png differ diff --git a/docs/topics/kickstarter-announcement.md b/docs/topics/kickstarter-announcement.md index cb8a1307..65475073 100644 --- a/docs/topics/kickstarter-announcement.md +++ b/docs/topics/kickstarter-announcement.md @@ -94,9 +94,9 @@ Our gold sponsors include companies large and small. Many thanks for their signi
  • Envision Linux
  • - +
    -
    +**Individual backers**: Xitij Ritesh Patel, Howard Sandford. --- @@ -111,6 +111,7 @@ The serious financial contribution that our silver sponsors have made is very mu
  • Providenz
  • alwaysdata.com
  • Triggered Messaging
  • +
  • PushPull Technology Ltd
  • Transcode
  • Garfo
  • Shippo
  • @@ -139,9 +140,26 @@ The serious financial contribution that our silver sponsors have made is very mu
  • OpenEye Scientific Software
  • Cantemo
  • MakeSpace
  • +
  • AX Semantics
  • +
  • ISL
  • -**Individual contributions**: Paul Hallet, Paul Whipp, Jannis Leidel, Johannes Spielmann, Rob Spectre, Chris Heisel, Marwan Alsabbagh. +**Individual backers**: Paul Hallet, Paul Whipp, Dylan Roy, Jannis Leidel, Xavier Ordoquy, Johannes Spielmann, Rob Spectre, Chris Heisel, Marwan Alsabbagh, Haris Ali, Tuomas Toivonen, Simon Haugk. + +--- + +### Advocates + +The following individuals made a significant financial contribution to the development of Django REST framework 3, for which I can only offer a huge, warm and sincere thank you! + +**Individual backers**: Jure Cuhalev, Kevin Brolly, Ferenc Szalai, Dougal Matthews, Stefan Foulis, Carlos Hernando, Alen Mujezinovic, Ross Crawford-d'Heureuse, George Kappel, Alasdair Nicol, John Carr, Steve Winton, Trey, Manuel Miranda, David Horn, Vince Mi, Daniel Sears, Jamie Matthews, Ryan Currah, Marty Kemka, Scott Nixon, Moshin Elahi, Kevin Campbell, Jose Antonio Leiva Izquierdo, Kevin Stone, Andrew Godwin, Tijs Teulings, Roger Boardman, Xavier Antoviaque, Darian Moody, Lujeni, Jon Dugan, Wiley Kestner, Daniel C. Silverstein, Daniel Hahler, Subodh Nijsure, Philipp Weidenhiller, Yusuke Muraoka, Danny Roa, Reto Aebersold, Kyle Getrost, Décébal Hormuz, James Dacosta, Matt Long, Mauro Rocco, Tyrel Souza, Ryan Campbell, Ville Jyrkkä, Charalampos Papaloizou, Nikolai Røed Kristiansen, Antoni Aloy López, Celia Oakley, Michał Krawczak, Ivan VenOsdel, Tim Watts, Martin Warne. + +**Corporate backers**: Savannah Informatics, Prism Skylabs. + +--- + +### Supporters +There were also almost 300 further individuals choosing to help fund the project at other levels or choosing to give anonymously. Again, thank you, thank you, thank you! \ No newline at end of file -- cgit v1.2.3 From e624871a687b9d723f0aa6c7d26cd25ed032a772 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Fri, 15 Aug 2014 15:46:26 +0100 Subject: Latest backer update --- docs/topics/kickstarter-announcement.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/topics/kickstarter-announcement.md b/docs/topics/kickstarter-announcement.md index 65475073..48c4673b 100644 --- a/docs/topics/kickstarter-announcement.md +++ b/docs/topics/kickstarter-announcement.md @@ -154,7 +154,7 @@ The serious financial contribution that our silver sponsors have made is very mu The following individuals made a significant financial contribution to the development of Django REST framework 3, for which I can only offer a huge, warm and sincere thank you! -**Individual backers**: Jure Cuhalev, Kevin Brolly, Ferenc Szalai, Dougal Matthews, Stefan Foulis, Carlos Hernando, Alen Mujezinovic, Ross Crawford-d'Heureuse, George Kappel, Alasdair Nicol, John Carr, Steve Winton, Trey, Manuel Miranda, David Horn, Vince Mi, Daniel Sears, Jamie Matthews, Ryan Currah, Marty Kemka, Scott Nixon, Moshin Elahi, Kevin Campbell, Jose Antonio Leiva Izquierdo, Kevin Stone, Andrew Godwin, Tijs Teulings, Roger Boardman, Xavier Antoviaque, Darian Moody, Lujeni, Jon Dugan, Wiley Kestner, Daniel C. Silverstein, Daniel Hahler, Subodh Nijsure, Philipp Weidenhiller, Yusuke Muraoka, Danny Roa, Reto Aebersold, Kyle Getrost, Décébal Hormuz, James Dacosta, Matt Long, Mauro Rocco, Tyrel Souza, Ryan Campbell, Ville Jyrkkä, Charalampos Papaloizou, Nikolai Røed Kristiansen, Antoni Aloy López, Celia Oakley, Michał Krawczak, Ivan VenOsdel, Tim Watts, Martin Warne. +**Individual backers**: Jure Cuhalev, Kevin Brolly, Ferenc Szalai, Dougal Matthews, Stefan Foulis, Carlos Hernando, Alen Mujezinovic, Ross Crawford-d'Heureuse, George Kappel, Alasdair Nicol, John Carr, Steve Winton, Trey, Manuel Miranda, David Horn, Vince Mi, Daniel Sears, Jamie Matthews, Ryan Currah, Marty Kemka, Scott Nixon, Moshin Elahi, Kevin Campbell, Jose Antonio Leiva Izquierdo, Kevin Stone, Andrew Godwin, Tijs Teulings, Roger Boardman, Xavier Antoviaque, Darian Moody, Lujeni, Jon Dugan, Wiley Kestner, Daniel C. Silverstein, Daniel Hahler, Subodh Nijsure, Philipp Weidenhiller, Yusuke Muraoka, Danny Roa, Reto Aebersold, Kyle Getrost, Décébal Hormuz, James Dacosta, Matt Long, Mauro Rocco, Tyrel Souza, Ryan Campbell, Ville Jyrkkä, Charalampos Papaloizou, Nikolai Røed Kristiansen, Antoni Aloy López, Celia Oakley, Michał Krawczak, Ivan VenOsdel, Tim Watts, Martin Warne, Nicola Jordan. **Corporate backers**: Savannah Informatics, Prism Skylabs. -- cgit v1.2.3 From 4c60639595db16e5b102f3dc20992ccb233b9a80 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Fri, 15 Aug 2014 16:19:13 +0100 Subject: Added Holvi --- docs/img/sponsors/3-holvi.png | Bin 0 -> 7533 bytes docs/topics/kickstarter-announcement.md | 1 + 2 files changed, 1 insertion(+) create mode 100644 docs/img/sponsors/3-holvi.png diff --git a/docs/img/sponsors/3-holvi.png b/docs/img/sponsors/3-holvi.png new file mode 100644 index 00000000..255e391e Binary files /dev/null and b/docs/img/sponsors/3-holvi.png differ diff --git a/docs/topics/kickstarter-announcement.md b/docs/topics/kickstarter-announcement.md index 48c4673b..fde2a5bc 100644 --- a/docs/topics/kickstarter-announcement.md +++ b/docs/topics/kickstarter-announcement.md @@ -138,6 +138,7 @@ The serious financial contribution that our silver sponsors have made is very mu
  • Aditium
  • OpenEye Scientific Software
  • +
  • Holvi
  • Cantemo
  • MakeSpace
  • AX Semantics
  • -- cgit v1.2.3 From 967798e83296a9d80fdbd847548d090e633156de Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Fri, 15 Aug 2014 17:39:51 +0100 Subject: Added compile to the sponsors --- docs/img/sponsors/2-compile.png | Bin 0 -> 3108 bytes docs/topics/kickstarter-announcement.md | 1 + 2 files changed, 1 insertion(+) create mode 100644 docs/img/sponsors/2-compile.png diff --git a/docs/img/sponsors/2-compile.png b/docs/img/sponsors/2-compile.png new file mode 100644 index 00000000..858aa09d Binary files /dev/null and b/docs/img/sponsors/2-compile.png differ diff --git a/docs/topics/kickstarter-announcement.md b/docs/topics/kickstarter-announcement.md index fde2a5bc..d91d2e41 100644 --- a/docs/topics/kickstarter-announcement.md +++ b/docs/topics/kickstarter-announcement.md @@ -91,6 +91,7 @@ Our gold sponsors include companies large and small. Many thanks for their signi
  • Crate
  • Cryptico Corp
  • NextHub
  • +
  • Compile
  • Envision Linux
  • -- cgit v1.2.3 From 172b9c74f9151a826162d5de703dc3b42e8147e9 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Fri, 15 Aug 2014 17:48:43 +0100 Subject: Latest sponsor update --- docs/topics/kickstarter-announcement.md | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/docs/topics/kickstarter-announcement.md b/docs/topics/kickstarter-announcement.md index d91d2e41..71bb48a6 100644 --- a/docs/topics/kickstarter-announcement.md +++ b/docs/topics/kickstarter-announcement.md @@ -81,8 +81,6 @@ Our gold sponsors include companies large and small. Many thanks for their signi
  • Lightning Kite
  • Opbeat
  • Koordinates
  • - -
  • Heroku
  • Galileo Press
  • Security Compass
  • @@ -97,7 +95,7 @@ Our gold sponsors include companies large and small. Many thanks for their signi
    -**Individual backers**: Xitij Ritesh Patel, Howard Sandford. +**Individual backers**: Xitij Ritesh Patel, Howard Sandford, Simon Haugk. --- @@ -116,7 +114,6 @@ The serious financial contribution that our silver sponsors have made is very mu
  • Transcode
  • Garfo
  • Shippo
  • -
  • Gizmag
  • Tivix
  • Safari
  • @@ -124,7 +121,6 @@ The serious financial contribution that our silver sponsors have made is very mu
  • ABA Systems
  • beefarm.ru
  • Vzzual.com
  • -
  • Infinite Code
  • Crossword Tracker
  • PkgFarm
  • @@ -136,7 +132,6 @@ The serious financial contribution that our silver sponsors have made is very mu
  • TrackMaven
  • Phurba
  • Nephila
  • -
  • Aditium
  • OpenEye Scientific Software
  • Holvi
  • @@ -148,7 +143,7 @@ The serious financial contribution that our silver sponsors have made is very mu
    -**Individual backers**: Paul Hallet, Paul Whipp, Dylan Roy, Jannis Leidel, Xavier Ordoquy, Johannes Spielmann, Rob Spectre, Chris Heisel, Marwan Alsabbagh, Haris Ali, Tuomas Toivonen, Simon Haugk. +**Individual backers**: Paul Hallet, Paul Whipp, Dylan Roy, Jannis Leidel, Xavier Ordoquy, Johannes Spielmann, Rob Spectre, Chris Heisel, Marwan Alsabbagh, Haris Ali, Tuomas Toivonen. --- -- cgit v1.2.3 From 14867705e90b2b5f7e84dc7385d4ffba0c82b3e1 Mon Sep 17 00:00:00 2001 From: sshquack Date: Fri, 15 Aug 2014 20:41:21 -0600 Subject: Specify file names using standard format + Explicitly specify module names in the standard format similar to all the other tutorials + Remove the extra quote around module name --- docs/tutorial/4-authentication-and-permissions.md | 2 +- docs/tutorial/5-relationships-and-hyperlinked-apis.md | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/tutorial/4-authentication-and-permissions.md b/docs/tutorial/4-authentication-and-permissions.md index 491df160..bdbe00ab 100644 --- a/docs/tutorial/4-authentication-and-permissions.md +++ b/docs/tutorial/4-authentication-and-permissions.md @@ -129,7 +129,7 @@ Then, add the following property to **both** the `SnippetList` and `SnippetDetai If you open a browser and navigate to the browsable API at the moment, you'll find that you're no longer able to create new code snippets. In order to do so we'd need to be able to login as a user. -We can add a login view for use with the browsable API, by editing the URLconf in our project-level urls.py file. +We can add a login view for use with the browsable API, by editing the URLconf in our project-level `urls.py` file. Add the following import at the top of the file: diff --git a/docs/tutorial/5-relationships-and-hyperlinked-apis.md b/docs/tutorial/5-relationships-and-hyperlinked-apis.md index aef92d08..deddb13f 100644 --- a/docs/tutorial/5-relationships-and-hyperlinked-apis.md +++ b/docs/tutorial/5-relationships-and-hyperlinked-apis.md @@ -4,7 +4,7 @@ At the moment relationships within our API are represented by using primary keys ## Creating an endpoint for the root of our API -Right now we have endpoints for 'snippets' and 'users', but we don't have a single entry point to our API. To create one, we'll use a regular function-based view and the `@api_view` decorator we introduced earlier. +Right now we have endpoints for 'snippets' and 'users', but we don't have a single entry point to our API. To create one, we'll use a regular function-based view and the `@api_view` decorator we introduced earlier. In your `snippets/views.py` add: from rest_framework import renderers from rest_framework.decorators import api_view @@ -29,7 +29,7 @@ Unlike all our other API endpoints, we don't want to use JSON, but instead just The other thing we need to consider when creating the code highlight view is that there's no existing concrete generic view that we can use. We're not returning an object instance, but instead a property of an object instance. -Instead of using a concrete generic view, we'll use the base class for representing instances, and create our own `.get()` method. In your `snippets.views` add: +Instead of using a concrete generic view, we'll use the base class for representing instances, and create our own `.get()` method. In your `snippets/views.py` add: from rest_framework import renderers from rest_framework.response import Response @@ -43,7 +43,7 @@ Instead of using a concrete generic view, we'll use the base class for represent return Response(snippet.highlighted) As usual we need to add the new views that we've created in to our URLconf. -We'll add a url pattern for our new API root: +We'll add a url pattern for our new API root in `snippets/urls.py`: url(r'^$', 'api_root'), @@ -73,7 +73,7 @@ The `HyperlinkedModelSerializer` has the following differences from `ModelSerial * Relationships use `HyperlinkedRelatedField`, instead of `PrimaryKeyRelatedField`. -We can easily re-write our existing serializers to use hyperlinking. +We can easily re-write our existing serializers to use hyperlinking. In your `snippets/serializers.py` add: class SnippetSerializer(serializers.HyperlinkedModelSerializer): owner = serializers.Field(source='owner.username') @@ -105,7 +105,7 @@ If we're going to have a hyperlinked API, we need to make sure we name our URL p * Our user serializer includes a field that refers to `'snippet-detail'`. * Our snippet and user serializers include `'url'` fields that by default will refer to `'{model_name}-detail'`, which in this case will be `'snippet-detail'` and `'user-detail'`. -After adding all those names into our URLconf, our final `'urls.py'` file should look something like this: +After adding all those names into our URLconf, our final `snippets/urls.py` file should look something like this: # API endpoints urlpatterns = format_suffix_patterns(patterns('snippets.views', -- cgit v1.2.3 From 867e441ec07fc182569c3dbe6f86fe42aa6b0cbf Mon Sep 17 00:00:00 2001 From: sshquack Date: Fri, 15 Aug 2014 20:45:28 -0600 Subject: Strip trailing spaces in tutorial --- docs/tutorial/1-serialization.md | 20 ++++++------ docs/tutorial/2-requests-and-responses.md | 8 ++--- docs/tutorial/3-class-based-views.md | 4 +-- docs/tutorial/4-authentication-and-permissions.md | 12 +++---- .../5-relationships-and-hyperlinked-apis.md | 16 ++++----- docs/tutorial/quickstart.md | 38 +++++++++++----------- 6 files changed, 49 insertions(+), 49 deletions(-) diff --git a/docs/tutorial/1-serialization.md b/docs/tutorial/1-serialization.md index 55b19457..96214f5b 100644 --- a/docs/tutorial/1-serialization.md +++ b/docs/tutorial/1-serialization.md @@ -81,8 +81,8 @@ For the purposes of this tutorial we're going to start by creating a simple `Sni LEXERS = [item for item in get_all_lexers() if item[1]] LANGUAGE_CHOICES = sorted([(item[1][0], item[0]) for item in LEXERS]) STYLE_CHOICES = sorted((item, item) for item in get_all_styles()) - - + + class Snippet(models.Model): created = models.DateTimeField(auto_now_add=True) title = models.CharField(max_length=100, blank=True, default='') @@ -94,7 +94,7 @@ For the purposes of this tutorial we're going to start by creating a simple `Sni style = models.CharField(choices=STYLE_CHOICES, default='friendly', max_length=100) - + class Meta: ordering = ('created',) @@ -122,12 +122,12 @@ The first thing we need to get started on our Web API is to provide a way of ser default='python') style = serializers.ChoiceField(choices=STYLE_CHOICES, default='friendly') - + def restore_object(self, attrs, instance=None): """ Create or update a new snippet instance, given a dictionary of deserialized field values. - + Note that if we don't define this method, then deserializing data will simply return a dictionary of items. """ @@ -180,7 +180,7 @@ At this point we've translated the model instance into Python native datatypes. content # '{"pk": 2, "title": "", "code": "print \\"hello, world\\"\\n", "linenos": false, "language": "python", "style": "friendly"}' -Deserialization is similar. First we parse a stream into Python native datatypes... +Deserialization is similar. First we parse a stream into Python native datatypes... # This import will use either `StringIO.StringIO` or `io.BytesIO` # as appropriate, depending on if we're running Python 2 or Python 3. @@ -196,7 +196,7 @@ Deserialization is similar. First we parse a stream into Python native datatype # True serializer.object # - + Notice how similar the API is to working with forms. The similarity should become even more apparent when we start writing views that use our serializer. We can also serialize querysets instead of model instances. To do so we simply add a `many=True` flag to the serializer arguments. @@ -264,7 +264,7 @@ The root of our API is going to be a view that supports listing all the existing return JSONResponse(serializer.data, status=201) return JSONResponse(serializer.errors, status=400) -Note that because we want to be able to POST to this view from clients that won't have a CSRF token we need to mark the view as `csrf_exempt`. This isn't something that you'd normally want to do, and REST framework views actually use more sensible behavior than this, but it'll do for our purposes right now. +Note that because we want to be able to POST to this view from clients that won't have a CSRF token we need to mark the view as `csrf_exempt`. This isn't something that you'd normally want to do, and REST framework views actually use more sensible behavior than this, but it'll do for our purposes right now. We'll also need a view which corresponds to an individual snippet, and can be used to retrieve, update or delete the snippet. @@ -277,11 +277,11 @@ We'll also need a view which corresponds to an individual snippet, and can be us snippet = Snippet.objects.get(pk=pk) except Snippet.DoesNotExist: return HttpResponse(status=404) - + if request.method == 'GET': serializer = SnippetSerializer(snippet) return JSONResponse(serializer.data) - + elif request.method == 'PUT': data = JSONParser().parse(request) serializer = SnippetSerializer(snippet, data=data) diff --git a/docs/tutorial/2-requests-and-responses.md b/docs/tutorial/2-requests-and-responses.md index 603edd08..e70bbbfc 100644 --- a/docs/tutorial/2-requests-and-responses.md +++ b/docs/tutorial/2-requests-and-responses.md @@ -33,7 +33,7 @@ The wrappers also provide behaviour such as returning `405 Method Not Allowed` r ## Pulling it all together -Okay, let's go ahead and start using these new components to write a few views. +Okay, let's go ahead and start using these new components to write a few views. We don't need our `JSONResponse` class in `views.py` anymore, so go ahead and delete that. Once that's done we can start refactoring our views slightly. @@ -69,7 +69,7 @@ Here is the view for an individual snippet, in the `views.py` module. def snippet_detail(request, pk): """ Retrieve, update or delete a snippet instance. - """ + """ try: snippet = Snippet.objects.get(pk=pk) except Snippet.DoesNotExist: @@ -115,7 +115,7 @@ Now update the `urls.py` file slightly, to append a set of `format_suffix_patter url(r'^snippets/$', 'snippet_list'), url(r'^snippets/(?P[0-9]+)$', 'snippet_detail'), ) - + urlpatterns = format_suffix_patterns(urlpatterns) We don't necessarily need to add these extra url patterns in, but it gives us a simple, clean way of referring to a specific format. @@ -146,7 +146,7 @@ Similarly, we can control the format of the request that we send, using the `Con curl -X POST http://127.0.0.1:8000/snippets/ -d "code=print 123" {"id": 3, "title": "", "code": "print 123", "linenos": false, "language": "python", "style": "friendly"} - + # POST using JSON curl -X POST http://127.0.0.1:8000/snippets/ -d '{"code": "print 456"}' -H "Content-Type: application/json" diff --git a/docs/tutorial/3-class-based-views.md b/docs/tutorial/3-class-based-views.md index b37bc31b..e04072ca 100644 --- a/docs/tutorial/3-class-based-views.md +++ b/docs/tutorial/3-class-based-views.md @@ -30,7 +30,7 @@ We'll start by rewriting the root view as a class based view. All this involves return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) -So far, so good. It looks pretty similar to the previous case, but we've got better separation between the different HTTP methods. We'll also need to update the instance view in `views.py`. +So far, so good. It looks pretty similar to the previous case, but we've got better separation between the different HTTP methods. We'll also need to update the instance view in `views.py`. class SnippetDetail(APIView): """ @@ -72,7 +72,7 @@ We'll also need to refactor our `urls.py` slightly now we're using class based v url(r'^snippets/$', views.SnippetList.as_view()), url(r'^snippets/(?P[0-9]+)/$', views.SnippetDetail.as_view()), ) - + urlpatterns = format_suffix_patterns(urlpatterns) Okay, we're done. If you run the development server everything should be working just as before. diff --git a/docs/tutorial/4-authentication-and-permissions.md b/docs/tutorial/4-authentication-and-permissions.md index bdbe00ab..74ad9a55 100644 --- a/docs/tutorial/4-authentication-and-permissions.md +++ b/docs/tutorial/4-authentication-and-permissions.md @@ -73,12 +73,12 @@ We'll also add a couple of views to `views.py`. We'd like to just use read-only class UserList(generics.ListAPIView): queryset = User.objects.all() serializer_class = UserSerializer - - + + class UserDetail(generics.RetrieveAPIView): queryset = User.objects.all() serializer_class = UserSerializer - + Make sure to also import the `UserSerializer` class from snippets.serializers import UserSerializer @@ -157,8 +157,8 @@ To do that we're going to need to create a custom permission. In the snippets app, create a new file, `permissions.py` from rest_framework import permissions - - + + class IsOwnerOrReadOnly(permissions.BasePermission): """ Custom permission to only allow owners of an object to edit it. @@ -201,7 +201,7 @@ If we try to create a snippet without authenticating, we'll get an error: We can make a successful request by including the username and password of one of the users we created earlier. curl -X POST http://127.0.0.1:8000/snippets/ -d "code=print 789" -u tom:password - + {"id": 5, "owner": "tom", "title": "foo", "code": "print 789", "linenos": false, "language": "python", "style": "friendly"} ## Summary diff --git a/docs/tutorial/5-relationships-and-hyperlinked-apis.md b/docs/tutorial/5-relationships-and-hyperlinked-apis.md index deddb13f..9c61fe3d 100644 --- a/docs/tutorial/5-relationships-and-hyperlinked-apis.md +++ b/docs/tutorial/5-relationships-and-hyperlinked-apis.md @@ -1,6 +1,6 @@ # Tutorial 5: Relationships & Hyperlinked APIs -At the moment relationships within our API are represented by using primary keys. In this part of the tutorial we'll improve the cohesion and discoverability of our API, by instead using hyperlinking for relationships. +At the moment relationships within our API are represented by using primary keys. In this part of the tutorial we'll improve the cohesion and discoverability of our API, by instead using hyperlinking for relationships. ## Creating an endpoint for the root of our API @@ -37,7 +37,7 @@ Instead of using a concrete generic view, we'll use the base class for represent class SnippetHighlight(generics.GenericAPIView): queryset = Snippet.objects.all() renderer_classes = (renderers.StaticHTMLRenderer,) - + def get(self, request, *args, **kwargs): snippet = self.get_object() return Response(snippet.highlighted) @@ -78,16 +78,16 @@ We can easily re-write our existing serializers to use hyperlinking. In your `sn class SnippetSerializer(serializers.HyperlinkedModelSerializer): owner = serializers.Field(source='owner.username') highlight = serializers.HyperlinkedIdentityField(view_name='snippet-highlight', format='html') - + class Meta: model = Snippet fields = ('url', 'highlight', 'owner', 'title', 'code', 'linenos', 'language', 'style') - - + + class UserSerializer(serializers.HyperlinkedModelSerializer): snippets = serializers.HyperlinkedRelatedField(many=True, view_name='snippet-detail') - + class Meta: model = User fields = ('url', 'username', 'snippets') @@ -126,9 +126,9 @@ After adding all those names into our URLconf, our final `snippets/urls.py` file views.UserDetail.as_view(), name='user-detail') )) - + # Login and logout views for the browsable API - urlpatterns += patterns('', + urlpatterns += patterns('', url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')), ) diff --git a/docs/tutorial/quickstart.md b/docs/tutorial/quickstart.md index 8bf8c7f5..029b56a2 100644 --- a/docs/tutorial/quickstart.md +++ b/docs/tutorial/quickstart.md @@ -46,14 +46,14 @@ First up we're going to define some serializers in `quickstart/serializers.py` t from django.contrib.auth.models import User, Group from rest_framework import serializers - - + + class UserSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = User fields = ('url', 'username', 'email', 'groups') - - + + class GroupSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = Group @@ -68,16 +68,16 @@ Right, we'd better write some views then. Open `quickstart/views.py` and get ty from django.contrib.auth.models import User, Group from rest_framework import viewsets from quickstart.serializers import UserSerializer, GroupSerializer - - + + class UserViewSet(viewsets.ModelViewSet): """ API endpoint that allows users to be viewed or edited. """ queryset = User.objects.all() serializer_class = UserSerializer - - + + class GroupViewSet(viewsets.ModelViewSet): """ API endpoint that allows groups to be viewed or edited. @@ -144,22 +144,22 @@ We're now ready to test the API we've built. Let's fire up the server from the We can now access our API, both from the command-line, using tools like `curl`... - bash: curl -H 'Accept: application/json; indent=4' -u admin:password http://127.0.0.1:8000/users/ + bash: curl -H 'Accept: application/json; indent=4' -u admin:password http://127.0.0.1:8000/users/ { - "count": 2, - "next": null, - "previous": null, + "count": 2, + "next": null, + "previous": null, "results": [ { - "email": "admin@example.com", - "groups": [], - "url": "http://127.0.0.1:8000/users/1/", + "email": "admin@example.com", + "groups": [], + "url": "http://127.0.0.1:8000/users/1/", "username": "admin" - }, + }, { - "email": "tom@example.com", - "groups": [ ], - "url": "http://127.0.0.1:8000/users/2/", + "email": "tom@example.com", + "groups": [ ], + "url": "http://127.0.0.1:8000/users/2/", "username": "tom" } ] -- cgit v1.2.3 From 38a0e3e6278db96660c89bfcb3e660704c068ff5 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Sat, 16 Aug 2014 14:02:44 +0100 Subject: Sponsor update --- docs/topics/kickstarter-announcement.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/topics/kickstarter-announcement.md b/docs/topics/kickstarter-announcement.md index 71bb48a6..84dc8511 100644 --- a/docs/topics/kickstarter-announcement.md +++ b/docs/topics/kickstarter-announcement.md @@ -151,9 +151,9 @@ The serious financial contribution that our silver sponsors have made is very mu The following individuals made a significant financial contribution to the development of Django REST framework 3, for which I can only offer a huge, warm and sincere thank you! -**Individual backers**: Jure Cuhalev, Kevin Brolly, Ferenc Szalai, Dougal Matthews, Stefan Foulis, Carlos Hernando, Alen Mujezinovic, Ross Crawford-d'Heureuse, George Kappel, Alasdair Nicol, John Carr, Steve Winton, Trey, Manuel Miranda, David Horn, Vince Mi, Daniel Sears, Jamie Matthews, Ryan Currah, Marty Kemka, Scott Nixon, Moshin Elahi, Kevin Campbell, Jose Antonio Leiva Izquierdo, Kevin Stone, Andrew Godwin, Tijs Teulings, Roger Boardman, Xavier Antoviaque, Darian Moody, Lujeni, Jon Dugan, Wiley Kestner, Daniel C. Silverstein, Daniel Hahler, Subodh Nijsure, Philipp Weidenhiller, Yusuke Muraoka, Danny Roa, Reto Aebersold, Kyle Getrost, Décébal Hormuz, James Dacosta, Matt Long, Mauro Rocco, Tyrel Souza, Ryan Campbell, Ville Jyrkkä, Charalampos Papaloizou, Nikolai Røed Kristiansen, Antoni Aloy López, Celia Oakley, Michał Krawczak, Ivan VenOsdel, Tim Watts, Martin Warne, Nicola Jordan. +**Individual backers**: Jure Cuhalev, Kevin Brolly, Ferenc Szalai, Dougal Matthews, Stefan Foulis, Carlos Hernando, Alen Mujezinovic, Ross Crawford-d'Heureuse, George Kappel, Alasdair Nicol, John Carr, Steve Winton, Trey, Manuel Miranda, David Horn, Vince Mi, Daniel Sears, Jamie Matthews, Ryan Currah, Marty Kemka, Scott Nixon, Moshin Elahi, Kevin Campbell, Jose Antonio Leiva Izquierdo, Kevin Stone, Andrew Godwin, Tijs Teulings, Roger Boardman, Xavier Antoviaque, Darian Moody, Lujeni, Jon Dugan, Wiley Kestner, Daniel C. Silverstein, Daniel Hahler, Subodh Nijsure, Philipp Weidenhiller, Yusuke Muraoka, Danny Roa, Reto Aebersold, Kyle Getrost, Décébal Hormuz, James Dacosta, Matt Long, Mauro Rocco, Tyrel Souza, Ryan Campbell, Ville Jyrkkä, Charalampos Papaloizou, Nikolai Røed Kristiansen, Antoni Aloy López, Celia Oakley, Michał Krawczak, Ivan VenOsdel, Tim Watts, Martin Warne, Nicola Jordan, Ryan Kaskel. -**Corporate backers**: Savannah Informatics, Prism Skylabs. +**Corporate backers**: Savannah Informatics, Prism Skylabs, Musical Operating Devices. --- -- cgit v1.2.3 From a6901ea36de19a35fa82783c984841b4c3ca0dad Mon Sep 17 00:00:00 2001 From: Aymeric Derbois Date: Sat, 16 Aug 2014 15:49:31 +0200 Subject: Add test for SerializerMethodField --- rest_framework/tests/test_fields.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/rest_framework/tests/test_fields.py b/rest_framework/tests/test_fields.py index b04b947f..17d12f23 100644 --- a/rest_framework/tests/test_fields.py +++ b/rest_framework/tests/test_fields.py @@ -1002,3 +1002,21 @@ class BooleanField(TestCase): bool_field = serializers.BooleanField(required=True) self.assertFalse(BooleanRequiredSerializer(data={}).is_valid()) + + +class SerializerMethodFieldTest(TestCase): + """ + Tests for the SerializerMethodField field_to_native() behavior + """ + class SerializerTest(serializers.Serializer): + def get_my_test(self, obj): + return obj.my_test[0:5] + + class Example(): + my_test = 'Hey, this is a test !' + + def test_field_to_native(self): + s = serializers.SerializerMethodField('get_my_test') + s.initialize(self.SerializerTest(), 'name') + result = s.field_to_native(self.Example(), None) + self.assertEqual(result, 'Hey, ') -- cgit v1.2.3 From 5f63d31b002020148c526f2d5ec27f723a06f2e9 Mon Sep 17 00:00:00 2001 From: Andrew Fong Date: Sat, 16 Aug 2014 15:05:46 -0700 Subject: override_method should substitute action A view's action is dependent on the request method. When overriding the method (e.g. to generate a form for a POST request on a GET call to the browseable API), the action should be updated as well. Otherwise, viewset functions may be in a weird limbo state where a 'list' action has a POST method.--- rest_framework/request.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rest_framework/request.py b/rest_framework/request.py index 40467c03..1ea61586 100644 --- a/rest_framework/request.py +++ b/rest_framework/request.py @@ -42,12 +42,16 @@ class override_method(object): self.view = view self.request = request self.method = method + self.action = getattr(view, 'action', None) def __enter__(self): self.view.request = clone_request(self.request, self.method) + action_map = getattr(self, 'action_map', {}) + self.view.action = action_map.get(self.method.lower()) return self.view.request def __exit__(self, *args, **kwarg): + self.view.action = self.action self.view.request = self.request -- cgit v1.2.3 From 21cbf3484e04bb015c1921307cdf0306a81e571d Mon Sep 17 00:00:00 2001 From: Andrew Fong Date: Sat, 16 Aug 2014 23:22:18 +0000 Subject: Fixed action_map being pulled from wrong object --- rest_framework/request.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest_framework/request.py b/rest_framework/request.py index 1ea61586..735a9288 100644 --- a/rest_framework/request.py +++ b/rest_framework/request.py @@ -46,7 +46,7 @@ class override_method(object): def __enter__(self): self.view.request = clone_request(self.request, self.method) - action_map = getattr(self, 'action_map', {}) + action_map = getattr(self.view, 'action_map', {}) self.view.action = action_map.get(self.method.lower()) return self.view.request -- cgit v1.2.3 From 6edbabe0e1ffa8111284c0af94a8f878f7056413 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Mon, 18 Aug 2014 10:58:00 +0100 Subject: Link to Django docs on widgets. Closes #1760. --- docs/api-guide/fields.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/api-guide/fields.md b/docs/api-guide/fields.md index dd279541..b41e0ebc 100644 --- a/docs/api-guide/fields.md +++ b/docs/api-guide/fields.md @@ -62,7 +62,7 @@ A dictionary of error codes to error messages. ### `widget` Used only if rendering the field to HTML. -This argument sets the widget that should be used to render the field. +This argument sets the widget that should be used to render the field. For more details, and a list of available widgets, see [the Django documentation on form widgets][django-widgets]. ### `label` @@ -370,6 +370,7 @@ The [django-rest-framework-gis][django-rest-framework-gis] package provides geog [FILE_UPLOAD_HANDLERS]: https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-FILE_UPLOAD_HANDLERS [ecma262]: http://ecma-international.org/ecma-262/5.1/#sec-15.9.1.15 [strftime]: http://docs.python.org/2/library/datetime.html#strftime-and-strptime-behavior +[django-widgets]: https://docs.djangoproject.com/en/dev/ref/forms/widgets/ [iso8601]: http://www.w3.org/TR/NOTE-datetime [drf-compound-fields]: http://drf-compound-fields.readthedocs.org [drf-extra-fields]: https://github.com/Hipo/drf-extra-fields -- cgit v1.2.3 From dce30207dae1725a2b08232fc4dee34e0949b14b Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Mon, 18 Aug 2014 11:09:53 +0100 Subject: Remove kickstarter links from homepage and README --- README.md | 10 ---------- docs/index.md | 8 -------- 2 files changed, 18 deletions(-) diff --git a/README.md b/README.md index eea002b4..da5f27ae 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,3 @@ ---- - -#### Django REST framework 3 - Kickstarter announcement! - -We are currently running a Kickstarter campaign to help fund the development of Django REST framework 3. - -If you want to help drive sustainable open-source development forward, then **please check out [the Kickstarter project](https://www.kickstarter.com/projects/tomchristie/django-rest-framework-3) and consider funding us.** - ---- - # Django REST framework [![build-status-image]][travis] diff --git a/docs/index.md b/docs/index.md index d9c686c4..dd407497 100644 --- a/docs/index.md +++ b/docs/index.md @@ -9,14 +9,6 @@ --- -#### Django REST framework 3 - Kickstarter announcement! - -We are currently running a Kickstarter campaign to help fund the development of Django REST framework 3. - -If you want to help drive sustainable open-source development **please [check out the Kickstarter project](https://www.kickstarter.com/projects/tomchristie/django-rest-framework-3) and consider funding us.** - ---- -