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(+)
(limited to 'rest_framework')
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.
---
rest_framework/templates/rest_framework/base.html | 2 ++
rest_framework/templates/rest_framework/login_base.html | 15 +++------------
2 files changed, 5 insertions(+), 12 deletions(-)
(limited to 'rest_framework')
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 %}
-
+ {% endblock %}
--
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(-)
(limited to 'rest_framework')
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(-)
(limited to 'rest_framework')
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 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(-)
(limited to 'rest_framework')
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 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.
---
rest_framework/generics.py | 8 ++++++++
1 file changed, 8 insertions(+)
(limited to 'rest_framework')
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 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(+)
(limited to 'rest_framework')
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(-)
(limited to 'rest_framework')
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(-)
(limited to 'rest_framework')
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 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(-)
(limited to 'rest_framework')
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 2d6469348de71f04507f00a5e0e608ae49829dd1 Mon Sep 17 00:00:00 2001
From: Jason Alan Palmer
Date: Tue, 5 Aug 2014 10:25:48 -0400
Subject: Remove duplicate class attributes
These duplicate attributes are ignored by at least Firefox and Chrome, so this change has no effect on the style---
rest_framework/templates/rest_framework/base.html | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
(limited to 'rest_framework')
diff --git a/rest_framework/templates/rest_framework/base.html b/rest_framework/templates/rest_framework/base.html
index 7067ee2f..e96fa8ec 100644
--- a/rest_framework/templates/rest_framework/base.html
+++ b/rest_framework/templates/rest_framework/base.html
@@ -93,7 +93,7 @@
{% endif %}
{% if options_form %}
-