From b0894edbeb9edc703414369ddc59c3cec1c092c1 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Wed, 1 Jun 2016 11:47:24 +0100 Subject: [PATCH 01/14] Added TEMPLATES setting to tests --- tests/conftest.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/conftest.py b/tests/conftest.py index 03b4e32852..f7b3d83869 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -15,6 +15,12 @@ def pytest_configure(): 'django.template.loaders.filesystem.Loader', 'django.template.loaders.app_directories.Loader', ), + TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'APP_DIRS': True, + }, + ], MIDDLEWARE_CLASSES=( 'django.middleware.common.CommonMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', From 1a2b3255ad38697c45823399bdd534fc19d554c0 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Wed, 1 Jun 2016 11:57:46 +0100 Subject: [PATCH 02/14] Remove deprecated view-string in URL conf --- tests/test_authentication.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_authentication.py b/tests/test_authentication.py index e7d2dd421b..6c411936d5 100644 --- a/tests/test_authentication.py +++ b/tests/test_authentication.py @@ -19,6 +19,7 @@ TokenAuthentication ) from rest_framework.authtoken.models import Token +from rest_framework.authtoken.views import obtain_auth_token from rest_framework.response import Response from rest_framework.test import APIClient, APIRequestFactory from rest_framework.views import APIView @@ -75,7 +76,7 @@ def put(self, request): authentication_classes=[CustomKeywordTokenAuthentication] ) ), - url(r'^auth-token/$', 'rest_framework.authtoken.views.obtain_auth_token'), + url(r'^auth-token/$', obtain_auth_token), url(r'^auth/', include('rest_framework.urls', namespace='rest_framework')), ] From f11e24ecff8a966da5b4a092fe1f500c18592173 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Wed, 1 Jun 2016 12:19:14 +0100 Subject: [PATCH 03/14] Replace 'urls = ...' in test classes with override_settings('ROOT_URLCONF=...') --- tests/browsable_api/test_browsable_api.py | 10 +++------- tests/test_authentication.py | 10 ++++------ tests/test_filters.py | 3 +-- tests/test_htmlrenderer.py | 8 +++----- tests/test_middleware.py | 6 ++---- tests/test_relations_hyperlink.py | 15 +++++---------- tests/test_renderers.py | 10 +++------- tests/test_request.py | 5 ++--- tests/test_response.py | 20 ++++++-------------- tests/test_reverse.py | 5 ++--- tests/test_routers.py | 11 ++++------- tests/test_testing.py | 5 ++--- tests/test_utils.py | 5 ++--- 13 files changed, 39 insertions(+), 74 deletions(-) diff --git a/tests/browsable_api/test_browsable_api.py b/tests/browsable_api/test_browsable_api.py index 153b4c189a..09b29ae1ba 100644 --- a/tests/browsable_api/test_browsable_api.py +++ b/tests/browsable_api/test_browsable_api.py @@ -1,16 +1,14 @@ from __future__ import unicode_literals from django.contrib.auth.models import User -from django.test import TestCase +from django.test import override_settings, TestCase from rest_framework.test import APIClient +@override_settings(ROOT_URLCONF='tests.browsable_api.auth_urls') class DropdownWithAuthTests(TestCase): """Tests correct dropdown behaviour with Auth views enabled.""" - - urls = 'tests.browsable_api.auth_urls' - def setUp(self): self.client = APIClient(enforce_csrf_checks=True) self.username = 'john' @@ -40,11 +38,9 @@ def test_login_shown_when_logged_out(self): self.assertContains(response, '>Log in<') +@override_settings(ROOT_URLCONF='tests.browsable_api.no_auth_urls') class NoDropdownWithoutAuthTests(TestCase): """Tests correct dropdown behaviour with Auth views NOT enabled.""" - - urls = 'tests.browsable_api.no_auth_urls' - def setUp(self): self.client = APIClient(enforce_csrf_checks=True) self.username = 'john' diff --git a/tests/test_authentication.py b/tests/test_authentication.py index 6c411936d5..db137b8adf 100644 --- a/tests/test_authentication.py +++ b/tests/test_authentication.py @@ -8,7 +8,7 @@ from django.contrib.auth.models import User from django.db import models from django.http import HttpResponse -from django.test import TestCase +from django.test import override_settings, TestCase from django.utils import six from rest_framework import ( @@ -81,10 +81,9 @@ def put(self, request): ] +@override_settings(ROOT_URLCONF='tests.test_authentication') class BasicAuthTests(TestCase): """Basic authentication""" - urls = 'tests.test_authentication' - def setUp(self): self.csrf_client = APIClient(enforce_csrf_checks=True) self.username = 'john' @@ -152,10 +151,9 @@ def test_post_json_failing_basic_auth(self): self.assertEqual(response['WWW-Authenticate'], 'Basic realm="api"') +@override_settings(ROOT_URLCONF='tests.test_authentication') class SessionAuthTests(TestCase): """User session authentication""" - urls = 'tests.test_authentication' - def setUp(self): self.csrf_client = APIClient(enforce_csrf_checks=True) self.non_csrf_client = APIClient(enforce_csrf_checks=False) @@ -222,9 +220,9 @@ def test_post_form_session_auth_failing(self): self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) +@override_settings(ROOT_URLCONF='tests.test_authentication') class BaseTokenAuthTests(object): """Token authentication""" - urls = 'tests.test_authentication' model = None path = None header_prefix = 'Token ' diff --git a/tests/test_filters.py b/tests/test_filters.py index 8493c96af7..fd71764f77 100644 --- a/tests/test_filters.py +++ b/tests/test_filters.py @@ -274,12 +274,11 @@ def test_unknown_filter(self): self.assertEqual(response.status_code, status.HTTP_200_OK) +@override_settings(ROOT_URLCONF='tests.test_filters') class IntegrationTestDetailFiltering(CommonFilteringTestCase): """ Integration tests for filtered detail views. """ - urls = 'tests.test_filters' - def _get_url(self, item): return reverse('detail-view', kwargs=dict(pk=item.pk)) diff --git a/tests/test_htmlrenderer.py b/tests/test_htmlrenderer.py index 01ef46d35c..649a7c9193 100644 --- a/tests/test_htmlrenderer.py +++ b/tests/test_htmlrenderer.py @@ -5,7 +5,7 @@ from django.core.exceptions import PermissionDenied from django.http import Http404 from django.template import Template, TemplateDoesNotExist -from django.test import TestCase +from django.test import override_settings, TestCase from django.utils import six from rest_framework import status @@ -43,9 +43,8 @@ def not_found(request): ] +@override_settings(ROOT_URLCONF='tests.test_htmlrenderer') class TemplateHTMLRendererTests(TestCase): - urls = 'tests.test_htmlrenderer' - def setUp(self): """ Monkeypatch get_template @@ -89,9 +88,8 @@ def test_permission_denied_html_view(self): self.assertEqual(response['Content-Type'], 'text/html; charset=utf-8') +@override_settings(ROOT_URLCONF='tests.test_htmlrenderer') class TemplateHTMLRendererExceptionTests(TestCase): - urls = 'tests.test_htmlrenderer' - def setUp(self): """ Monkeypatch get_template diff --git a/tests/test_middleware.py b/tests/test_middleware.py index 49124da612..a9f620c0e3 100644 --- a/tests/test_middleware.py +++ b/tests/test_middleware.py @@ -1,6 +1,6 @@ - from django.conf.urls import url from django.contrib.auth.models import User +from django.test import override_settings from rest_framework.authentication import TokenAuthentication from rest_framework.authtoken.models import Token @@ -20,10 +20,8 @@ def process_response(self, request, response): return response +@override_settings(ROOT_URLCONF='tests.test_middleware') class TestMiddleware(APITestCase): - - urls = 'tests.test_middleware' - def test_middleware_can_access_user_when_processing_response(self): user = User.objects.create_user('john', 'john@example.com', 'password') key = 'abcd1234' diff --git a/tests/test_relations_hyperlink.py b/tests/test_relations_hyperlink.py index c0642eda26..0eb22b2aa9 100644 --- a/tests/test_relations_hyperlink.py +++ b/tests/test_relations_hyperlink.py @@ -1,7 +1,7 @@ from __future__ import unicode_literals from django.conf.urls import url -from django.test import TestCase +from django.test import override_settings, TestCase from rest_framework import serializers from rest_framework.test import APIRequestFactory @@ -71,10 +71,8 @@ class Meta: # TODO: Add test that .data cannot be accessed prior to .is_valid - +@override_settings(ROOT_URLCONF='tests.test_relations_hyperlink') class HyperlinkedManyToManyTests(TestCase): - urls = 'tests.test_relations_hyperlink' - def setUp(self): for idx in range(1, 4): target = ManyToManyTarget(name='target-%d' % idx) @@ -188,9 +186,8 @@ def test_reverse_many_to_many_create(self): self.assertEqual(serializer.data, expected) +@override_settings(ROOT_URLCONF='tests.test_relations_hyperlink') class HyperlinkedForeignKeyTests(TestCase): - urls = 'tests.test_relations_hyperlink' - def setUp(self): target = ForeignKeyTarget(name='target-1') target.save() @@ -318,9 +315,8 @@ def test_foreign_key_update_with_invalid_null(self): self.assertEqual(serializer.errors, {'target': ['This field may not be null.']}) +@override_settings(ROOT_URLCONF='tests.test_relations_hyperlink') class HyperlinkedNullableForeignKeyTests(TestCase): - urls = 'tests.test_relations_hyperlink' - def setUp(self): target = ForeignKeyTarget(name='target-1') target.save() @@ -425,9 +421,8 @@ def test_foreign_key_update_with_valid_emptystring(self): self.assertEqual(serializer.data, expected) +@override_settings(ROOT_URLCONF='tests.test_relations_hyperlink') class HyperlinkedNullableOneToOneTests(TestCase): - urls = 'tests.test_relations_hyperlink' - def setUp(self): target = OneToOneTarget(name='target-1') target.save() diff --git a/tests/test_renderers.py b/tests/test_renderers.py index de89e50aaa..ca8eb0cff9 100644 --- a/tests/test_renderers.py +++ b/tests/test_renderers.py @@ -8,7 +8,7 @@ from django.conf.urls import include, url from django.core.cache import cache from django.db import models -from django.test import TestCase +from django.test import override_settings, TestCase from django.utils import six from django.utils.safestring import SafeText from django.utils.translation import ugettext_lazy as _ @@ -148,13 +148,11 @@ def test_only_permitted_forms_are_displayed(self): self.assertContains(response, '>PATCH<') +@override_settings(ROOT_URLCONF='tests.test_renderers') class RendererEndToEndTests(TestCase): """ End-to-end testing of renderers using an RendererMixin on a generic view. """ - - urls = 'tests.test_renderers' - def test_default_renderer_serializes_content(self): """If the Accept header is not set the default renderer should serialize the response.""" resp = self.client.get('/') @@ -397,13 +395,11 @@ class AsciiJSONRenderer(JSONRenderer): # Tests for caching issue, #346 +@override_settings(ROOT_URLCONF='tests.test_renderers') class CacheRenderTest(TestCase): """ Tests specific to caching responses """ - - urls = 'tests.test_renderers' - def test_head_caching(self): """ Test caching of HEAD requests diff --git a/tests/test_request.py b/tests/test_request.py index 7a0575789a..8219bd4ecf 100644 --- a/tests/test_request.py +++ b/tests/test_request.py @@ -7,7 +7,7 @@ from django.contrib.auth import authenticate, login, logout from django.contrib.auth.models import User from django.contrib.sessions.middleware import SessionMiddleware -from django.test import TestCase +from django.test import override_settings, TestCase from django.utils import six from rest_framework import status @@ -113,9 +113,8 @@ def post(self, request): ] +@override_settings(ROOT_URLCONF='tests.test_request') class TestContentParsingWithAuthentication(TestCase): - urls = 'tests.test_request' - def setUp(self): self.csrf_client = APIClient(enforce_csrf_checks=True) self.username = 'john' diff --git a/tests/test_response.py b/tests/test_response.py index df2d7b4ec2..f01b05774e 100644 --- a/tests/test_response.py +++ b/tests/test_response.py @@ -1,7 +1,7 @@ from __future__ import unicode_literals from django.conf.urls import include, url -from django.test import TestCase +from django.test import override_settings, TestCase from django.utils import six from rest_framework import generics, routers, serializers, status, viewsets @@ -131,13 +131,11 @@ class HTMLNewModelView(generics.ListCreateAPIView): # TODO: Clean tests bellow - remove duplicates with above, better unit testing, ... +@override_settings(ROOT_URLCONF='tests.test_response') class RendererIntegrationTests(TestCase): """ End-to-end testing of renderers using an ResponseMixin on a generic view. """ - - urls = 'tests.test_response' - def test_default_renderer_serializes_content(self): """If the Accept header is not set the default renderer should serialize the response.""" resp = self.client.get('/') @@ -201,9 +199,8 @@ def test_specified_renderer_is_used_on_format_query_with_matching_accept(self): self.assertEqual(resp.status_code, DUMMYSTATUS) +@override_settings(ROOT_URLCONF='tests.test_response') class UnsupportedMediaTypeTests(TestCase): - urls = 'tests.test_response' - def test_should_allow_posting_json(self): response = self.client.post('/json', data='{"test": 123}', content_type='application/json') @@ -220,12 +217,11 @@ def test_should_not_allow_posting_a_form(self): self.assertEqual(response.status_code, 415) +@override_settings(ROOT_URLCONF='tests.test_response') class Issue122Tests(TestCase): """ Tests that covers #122. """ - urls = 'tests.test_response' - def test_only_html_renderer(self): """ Test if no infinite recursion occurs. @@ -239,13 +235,11 @@ def test_html_renderer_is_first(self): self.client.get('/html1') +@override_settings(ROOT_URLCONF='tests.test_response') class Issue467Tests(TestCase): """ Tests for #467 """ - - urls = 'tests.test_response' - def test_form_has_label_and_help_text(self): resp = self.client.get('/html_new_model') self.assertEqual(resp['Content-Type'], 'text/html; charset=utf-8') @@ -253,13 +247,11 @@ def test_form_has_label_and_help_text(self): # self.assertContains(resp, 'Text description.') +@override_settings(ROOT_URLCONF='tests.test_response') class Issue807Tests(TestCase): """ Covers #807 """ - - urls = 'tests.test_response' - def test_does_not_append_charset_by_default(self): """ Renderers don't include a charset unless set explicitly. diff --git a/tests/test_reverse.py b/tests/test_reverse.py index c5486e5dba..0962efaf3b 100644 --- a/tests/test_reverse.py +++ b/tests/test_reverse.py @@ -2,7 +2,7 @@ from django.conf.urls import url from django.core.urlresolvers import NoReverseMatch -from django.test import TestCase +from django.test import override_settings, TestCase from rest_framework.reverse import reverse from rest_framework.test import APIRequestFactory @@ -30,12 +30,11 @@ def reverse(self, *args, **kwargs): return 'http://scheme-reversed/view' +@override_settings(ROOT_URLCONF='tests.test_reverse') class ReverseTests(TestCase): """ Tests for fully qualified URLs when using `reverse`. """ - urls = 'tests.test_reverse' - def test_reversed_urls_are_fully_qualified(self): request = factory.get('/view') url = reverse('view', request=request) diff --git a/tests/test_routers.py b/tests/test_routers.py index ae2639bf23..ae46708020 100644 --- a/tests/test_routers.py +++ b/tests/test_routers.py @@ -5,7 +5,7 @@ from django.conf.urls import include, url from django.core.exceptions import ImproperlyConfigured from django.db import models -from django.test import TestCase +from django.test import override_settings, TestCase from rest_framework import permissions, serializers, viewsets from rest_framework.decorators import detail_route, list_route @@ -113,9 +113,8 @@ def test_link_and_action_decorator(self): self.assertEqual(route.mapping[method], endpoint) +@override_settings(ROOT_URLCONF='tests.test_routers') class TestRootView(TestCase): - urls = 'tests.test_routers' - def test_retrieve_namespaced_root(self): response = self.client.get('/namespaced/') self.assertEqual( @@ -135,12 +134,11 @@ def test_retrieve_non_namespaced_root(self): ) +@override_settings(ROOT_URLCONF='tests.test_routers') class TestCustomLookupFields(TestCase): """ Ensure that custom lookup fields are correctly routed. """ - urls = 'tests.test_routers' - def setUp(self): RouterTestModel.objects.create(uuid='123', text='foo bar') @@ -191,14 +189,13 @@ def test_urls_limited_by_lookup_value_regex(self): self.assertEqual(expected[idx], self.urls[idx].regex.pattern) +@override_settings(ROOT_URLCONF='tests.test_routers') class TestLookupUrlKwargs(TestCase): """ Ensure the router honors lookup_url_kwarg. Setup a deep lookup_field, but map it to a simple URL kwarg. """ - urls = 'tests.test_routers' - def setUp(self): RouterTestModel.objects.create(uuid='123', text='foo bar') diff --git a/tests/test_testing.py b/tests/test_testing.py index e0bf759a4a..4fd20c33b7 100644 --- a/tests/test_testing.py +++ b/tests/test_testing.py @@ -6,7 +6,7 @@ from django.conf.urls import url from django.contrib.auth.models import User from django.shortcuts import redirect -from django.test import TestCase +from django.test import override_settings, TestCase from rest_framework.decorators import api_view from rest_framework.response import Response @@ -44,9 +44,8 @@ def redirect_view(request): ] +@override_settings(ROOT_URLCONF='tests.test_testing') class TestAPITestClient(TestCase): - urls = 'tests.test_testing' - def setUp(self): self.client = APIClient() diff --git a/tests/test_utils.py b/tests/test_utils.py index ca3d43061e..adb735511f 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -2,7 +2,7 @@ from django.conf.urls import url from django.core.exceptions import ImproperlyConfigured -from django.test import TestCase +from django.test import override_settings, TestCase from django.utils import six import rest_framework.utils.model_meta @@ -47,12 +47,11 @@ def get_view_name(self): ] +@override_settings(ROOT_URLCONF='tests.test_utils') class BreadcrumbTests(TestCase): """ Tests the breadcrumb functionality used by the HTML renderer. """ - urls = 'tests.test_utils' - def test_root_breadcrumbs(self): url = '/' self.assertEqual( From 9c83ff44a575f3c1e685011504209b24aeef85dc Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Wed, 1 Jun 2016 12:26:06 +0100 Subject: [PATCH 04/14] Refactor UsingURLPatterns to use override_settings(ROOT_URLCONF=...) style --- tests/test_versioning.py | 30 ++++++++++++++++++++++++++---- tests/utils.py | 24 ------------------------ 2 files changed, 26 insertions(+), 28 deletions(-) diff --git a/tests/test_versioning.py b/tests/test_versioning.py index 4029e0e43a..d4d8cfccb0 100644 --- a/tests/test_versioning.py +++ b/tests/test_versioning.py @@ -1,5 +1,6 @@ import pytest from django.conf.urls import include, url +from django.test import override_settings from rest_framework import serializers, status, versioning from rest_framework.decorators import APIView @@ -9,7 +10,28 @@ from rest_framework.test import APIRequestFactory, APITestCase from rest_framework.versioning import NamespaceVersioning -from .utils import UsingURLPatterns + +@override_settings(ROOT_URLCONF='tests.test_versioning') +class URLPatternsTestCase(APITestCase): + """ + Isolates URL patterns used during testing on the test class itself. + For example: + + class MyTestCase(URLPatternsTestCase): + urlpatterns = [ + ... + ] + + def test_something(self): + ... + """ + def setUp(self): + global urlpatterns + urlpatterns = self.urlpatterns + + def tearDown(self): + global urlpatterns + urlpatterns = [] class RequestVersionView(APIView): @@ -120,7 +142,7 @@ class FakeResolverMatch: assert response.data == {'version': None} -class TestURLReversing(UsingURLPatterns, APITestCase): +class TestURLReversing(URLPatternsTestCase): included = [ url(r'^namespaced/$', dummy_view, name='another'), url(r'^example/(?P\d+)/$', dummy_pk_view, name='example-detail') @@ -238,7 +260,7 @@ class FakeResolverMatch: assert response.status_code == status.HTTP_404_NOT_FOUND -class TestHyperlinkedRelatedField(UsingURLPatterns, APITestCase): +class TestHyperlinkedRelatedField(URLPatternsTestCase): included = [ url(r'^namespaced/(?P\d+)/$', dummy_pk_view, name='namespaced'), ] @@ -270,7 +292,7 @@ def test_bug_2489(self): self.field.to_internal_value('/v2/namespaced/3/') -class TestNamespaceVersioningHyperlinkedRelatedFieldScheme(UsingURLPatterns, APITestCase): +class TestNamespaceVersioningHyperlinkedRelatedFieldScheme(URLPatternsTestCase): included = [ url(r'^namespaced/(?P\d+)/$', dummy_pk_view, name='namespaced'), ] diff --git a/tests/utils.py b/tests/utils.py index b90349967d..5b2d75864a 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -2,30 +2,6 @@ from django.core.urlresolvers import NoReverseMatch -class UsingURLPatterns(object): - """ - Isolates URL patterns used during testing on the test class itself. - For example: - - class MyTestCase(UsingURLPatterns, TestCase): - urlpatterns = [ - ... - ] - - def test_something(self): - ... - """ - urls = __name__ - - def setUp(self): - global urlpatterns - urlpatterns = self.urlpatterns - - def tearDown(self): - global urlpatterns - urlpatterns = [] - - class MockObject(object): def __init__(self, **kwargs): self._kwargs = kwargs From 96aaa24e9b24a3d2938e3c0924bd456f12951d33 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Wed, 1 Jun 2016 12:47:44 +0100 Subject: [PATCH 05/14] Get model managers and names in a version-compatible manner. --- rest_framework/compat.py | 13 +++++++++++++ rest_framework/utils/representation.py | 8 ++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/rest_framework/compat.py b/rest_framework/compat.py index e435618a2f..d5c7a19d3f 100644 --- a/rest_framework/compat.py +++ b/rest_framework/compat.py @@ -58,6 +58,19 @@ def distinct(queryset, base): return queryset.distinct() +def get_names_and_managers(options): + if django.VERSION >= (1, 10): + return [ + (manager.name, manager) + for manager + in options.managers + ] + return [ + (manager_info[1], manager_info[2]) + for manager_info + in (options.concrete_managers + options.abstract_managers) + ] + # contrib.postgres only supported from 1.8 onwards. try: from django.contrib.postgres import fields as postgres_fields diff --git a/rest_framework/utils/representation.py b/rest_framework/utils/representation.py index 49f829c102..32e6d246a6 100644 --- a/rest_framework/utils/representation.py +++ b/rest_framework/utils/representation.py @@ -10,15 +10,15 @@ from django.utils.encoding import force_text from django.utils.functional import Promise -from rest_framework.compat import unicode_repr +from rest_framework.compat import get_names_and_managers, unicode_repr def manager_repr(value): model = value.model opts = model._meta - for _, name, manager in opts.concrete_managers + opts.abstract_managers: - if manager == value: - return '%s.%s.all()' % (model._meta.object_name, name) + for manager_name, manager_instance in get_names_and_managers(opts): + if manager_instance == value: + return '%s.%s.all()' % (model._meta.object_name, manager_name) return repr(value) From 46f2ec49da6ab3b7b8185dc5855cacd9df9a547f Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Wed, 1 Jun 2016 12:50:07 +0100 Subject: [PATCH 06/14] Apply override_settings to a TestCase, not a mixin class --- tests/test_authentication.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/test_authentication.py b/tests/test_authentication.py index db137b8adf..0330e50926 100644 --- a/tests/test_authentication.py +++ b/tests/test_authentication.py @@ -220,7 +220,6 @@ def test_post_form_session_auth_failing(self): self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) -@override_settings(ROOT_URLCONF='tests.test_authentication') class BaseTokenAuthTests(object): """Token authentication""" model = None @@ -310,6 +309,7 @@ def test_post_json_failing_token_auth(self): self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) +@override_settings(ROOT_URLCONF='tests.test_authentication') class TokenAuthTests(BaseTokenAuthTests, TestCase): model = Token path = '/token/' @@ -366,11 +366,13 @@ def test_token_login_form(self): self.assertEqual(response.data['token'], self.key) +@override_settings(ROOT_URLCONF='tests.test_authentication') class CustomTokenAuthTests(BaseTokenAuthTests, TestCase): model = CustomToken path = '/customtoken/' +@override_settings(ROOT_URLCONF='tests.test_authentication') class CustomKeywordTokenAuthTests(BaseTokenAuthTests, TestCase): model = Token path = '/customkeywordtoken/' From 9d1ee6f8964b9ab126a1c164456e73a48a39e750 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Wed, 1 Jun 2016 13:02:25 +0100 Subject: [PATCH 07/14] Use '.callback' property instead of private attributes when inspecting urlpatterns --- rest_framework/compat.py | 4 ++++ rest_framework/urlpatterns.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/rest_framework/compat.py b/rest_framework/compat.py index d5c7a19d3f..7a0aea3db2 100644 --- a/rest_framework/compat.py +++ b/rest_framework/compat.py @@ -60,17 +60,21 @@ def distinct(queryset, base): def get_names_and_managers(options): if django.VERSION >= (1, 10): + # Django 1.10 onwards provides a `.managers` property on the Options. return [ (manager.name, manager) for manager in options.managers ] + # For Django 1.8 and 1.9, use the three-tuple information provided + # by .concrete_managers and .abstract_managers return [ (manager_info[1], manager_info[2]) for manager_info in (options.concrete_managers + options.abstract_managers) ] + # contrib.postgres only supported from 1.8 onwards. try: from django.contrib.postgres import fields as postgres_fields diff --git a/rest_framework/urlpatterns.py b/rest_framework/urlpatterns.py index 5347b3bc1a..7a02bb0f0a 100644 --- a/rest_framework/urlpatterns.py +++ b/rest_framework/urlpatterns.py @@ -24,7 +24,7 @@ def apply_suffix_patterns(urlpatterns, suffix_pattern, suffix_required): else: # Regular URL pattern regex = urlpattern.regex.pattern.rstrip('$').rstrip('/') + suffix_pattern - view = urlpattern._callback or urlpattern._callback_str + view = urlpattern.callback kwargs = urlpattern.default_args name = urlpattern.name # Add in both the existing and the new urlpattern From 437a12579394ef65f67c4752e6a8a8992c31e9dc Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Wed, 1 Jun 2016 13:17:22 +0100 Subject: [PATCH 08/14] Pass 'user' to template explicitly --- rest_framework/renderers.py | 1 + tests/browsable_api/views.py | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rest_framework/renderers.py b/rest_framework/renderers.py index 63e0d836f5..264f7ac3b6 100644 --- a/rest_framework/renderers.py +++ b/rest_framework/renderers.py @@ -635,6 +635,7 @@ def get_context(self, data, accepted_media_type, renderer_context): 'view': view, 'request': request, 'response': response, + 'user': request.user, 'description': self.get_description(view, response.status_code), 'name': self.get_name(view), 'version': VERSION, diff --git a/tests/browsable_api/views.py b/tests/browsable_api/views.py index cd020cd326..03758f10b3 100644 --- a/tests/browsable_api/views.py +++ b/tests/browsable_api/views.py @@ -6,9 +6,8 @@ class MockView(APIView): - authentication_classes = (authentication.SessionAuthentication,) - renderer_classes = (renderers.BrowsableAPIRenderer,) + renderer_classes = (renderers.BrowsableAPIRenderer, renderers.JSONRenderer) def get(self, request): return Response({'a': 1, 'b': 2, 'c': 3}) From c65c5e4b2c962c4021eab958dc0874bbe1d19377 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Wed, 1 Jun 2016 13:20:45 +0100 Subject: [PATCH 09/14] Correct sorting of import statements. --- tests/browsable_api/test_browsable_api.py | 2 +- tests/test_atomic_requests.py | 2 +- tests/test_authentication.py | 2 +- tests/test_generics.py | 6 +++--- tests/test_htmlrenderer.py | 2 +- tests/test_multitable_inheritance.py | 2 +- tests/test_permissions.py | 2 +- tests/test_relations_hyperlink.py | 8 ++++---- tests/test_relations_pk.py | 4 ++-- tests/test_relations_slug.py | 4 ++-- tests/test_renderers.py | 2 +- tests/test_request.py | 2 +- tests/test_response.py | 4 ++-- tests/test_reverse.py | 2 +- tests/test_routers.py | 2 +- tests/test_testing.py | 2 +- tests/test_utils.py | 4 ++-- 17 files changed, 26 insertions(+), 26 deletions(-) diff --git a/tests/browsable_api/test_browsable_api.py b/tests/browsable_api/test_browsable_api.py index 09b29ae1ba..3d49c353b5 100644 --- a/tests/browsable_api/test_browsable_api.py +++ b/tests/browsable_api/test_browsable_api.py @@ -1,7 +1,7 @@ from __future__ import unicode_literals from django.contrib.auth.models import User -from django.test import override_settings, TestCase +from django.test import TestCase, override_settings from rest_framework.test import APIClient diff --git a/tests/test_atomic_requests.py b/tests/test_atomic_requests.py index 8342ad3aff..3e1d41725f 100644 --- a/tests/test_atomic_requests.py +++ b/tests/test_atomic_requests.py @@ -7,13 +7,13 @@ from django.http import Http404 from django.test import TestCase, TransactionTestCase from django.utils.decorators import method_decorator +from tests.models import BasicModel from rest_framework import status from rest_framework.exceptions import APIException from rest_framework.response import Response from rest_framework.test import APIRequestFactory from rest_framework.views import APIView -from tests.models import BasicModel factory = APIRequestFactory() diff --git a/tests/test_authentication.py b/tests/test_authentication.py index 0330e50926..b6377f6e87 100644 --- a/tests/test_authentication.py +++ b/tests/test_authentication.py @@ -8,7 +8,7 @@ from django.contrib.auth.models import User from django.db import models from django.http import HttpResponse -from django.test import override_settings, TestCase +from django.test import TestCase, override_settings from django.utils import six from rest_framework import ( diff --git a/tests/test_generics.py b/tests/test_generics.py index 2e47df50fb..b81a02fc3b 100644 --- a/tests/test_generics.py +++ b/tests/test_generics.py @@ -5,13 +5,13 @@ from django.shortcuts import get_object_or_404 from django.test import TestCase from django.utils import six +from tests.models import ( + BasicModel, ForeignKeySource, ForeignKeyTarget, RESTFrameworkModel +) from rest_framework import generics, renderers, serializers, status from rest_framework.response import Response from rest_framework.test import APIRequestFactory -from tests.models import ( - BasicModel, ForeignKeySource, ForeignKeyTarget, RESTFrameworkModel -) factory = APIRequestFactory() diff --git a/tests/test_htmlrenderer.py b/tests/test_htmlrenderer.py index 649a7c9193..3dfe6ef74d 100644 --- a/tests/test_htmlrenderer.py +++ b/tests/test_htmlrenderer.py @@ -5,7 +5,7 @@ from django.core.exceptions import PermissionDenied from django.http import Http404 from django.template import Template, TemplateDoesNotExist -from django.test import override_settings, TestCase +from django.test import TestCase, override_settings from django.utils import six from rest_framework import status diff --git a/tests/test_multitable_inheritance.py b/tests/test_multitable_inheritance.py index 340d4966a5..5867f19665 100644 --- a/tests/test_multitable_inheritance.py +++ b/tests/test_multitable_inheritance.py @@ -2,9 +2,9 @@ from django.db import models from django.test import TestCase +from tests.models import RESTFrameworkModel from rest_framework import serializers -from tests.models import RESTFrameworkModel # Models diff --git a/tests/test_permissions.py b/tests/test_permissions.py index e04c72ec97..f36b8f4dac 100644 --- a/tests/test_permissions.py +++ b/tests/test_permissions.py @@ -7,6 +7,7 @@ from django.core.urlresolvers import ResolverMatch from django.db import models from django.test import TestCase +from tests.models import BasicModel from rest_framework import ( HTTP_HEADER_ENCODING, authentication, generics, permissions, serializers, @@ -16,7 +17,6 @@ from rest_framework.filters import DjangoObjectPermissionsFilter from rest_framework.routers import DefaultRouter from rest_framework.test import APIRequestFactory -from tests.models import BasicModel factory = APIRequestFactory() diff --git a/tests/test_relations_hyperlink.py b/tests/test_relations_hyperlink.py index 0eb22b2aa9..27e1d14493 100644 --- a/tests/test_relations_hyperlink.py +++ b/tests/test_relations_hyperlink.py @@ -1,15 +1,15 @@ from __future__ import unicode_literals from django.conf.urls import url -from django.test import override_settings, TestCase - -from rest_framework import serializers -from rest_framework.test import APIRequestFactory +from django.test import TestCase, override_settings from tests.models import ( ForeignKeySource, ForeignKeyTarget, ManyToManySource, ManyToManyTarget, NullableForeignKeySource, NullableOneToOneSource, OneToOneTarget ) +from rest_framework import serializers +from rest_framework.test import APIRequestFactory + factory = APIRequestFactory() request = factory.get('/') # Just to ensure we have a request in the serializer context diff --git a/tests/test_relations_pk.py b/tests/test_relations_pk.py index ba75bd94fe..c82188ede8 100644 --- a/tests/test_relations_pk.py +++ b/tests/test_relations_pk.py @@ -2,14 +2,14 @@ from django.test import TestCase from django.utils import six - -from rest_framework import serializers from tests.models import ( ForeignKeySource, ForeignKeyTarget, ManyToManySource, ManyToManyTarget, NullableForeignKeySource, NullableOneToOneSource, NullableUUIDForeignKeySource, OneToOneTarget, UUIDForeignKeyTarget ) +from rest_framework import serializers + # ManyToMany class ManyToManyTargetSerializer(serializers.ModelSerializer): diff --git a/tests/test_relations_slug.py b/tests/test_relations_slug.py index 680aee4173..cee18031d3 100644 --- a/tests/test_relations_slug.py +++ b/tests/test_relations_slug.py @@ -1,10 +1,10 @@ from django.test import TestCase - -from rest_framework import serializers from tests.models import ( ForeignKeySource, ForeignKeyTarget, NullableForeignKeySource ) +from rest_framework import serializers + class ForeignKeyTargetSerializer(serializers.ModelSerializer): sources = serializers.SlugRelatedField( diff --git a/tests/test_renderers.py b/tests/test_renderers.py index ca8eb0cff9..5793fc7346 100644 --- a/tests/test_renderers.py +++ b/tests/test_renderers.py @@ -8,7 +8,7 @@ from django.conf.urls import include, url from django.core.cache import cache from django.db import models -from django.test import override_settings, TestCase +from django.test import TestCase, override_settings from django.utils import six from django.utils.safestring import SafeText from django.utils.translation import ugettext_lazy as _ diff --git a/tests/test_request.py b/tests/test_request.py index 8219bd4ecf..dee636d766 100644 --- a/tests/test_request.py +++ b/tests/test_request.py @@ -7,7 +7,7 @@ from django.contrib.auth import authenticate, login, logout from django.contrib.auth.models import User from django.contrib.sessions.middleware import SessionMiddleware -from django.test import override_settings, TestCase +from django.test import TestCase, override_settings from django.utils import six from rest_framework import status diff --git a/tests/test_response.py b/tests/test_response.py index f01b05774e..28ea90ce4e 100644 --- a/tests/test_response.py +++ b/tests/test_response.py @@ -1,8 +1,9 @@ from __future__ import unicode_literals from django.conf.urls import include, url -from django.test import override_settings, TestCase +from django.test import TestCase, override_settings from django.utils import six +from tests.models import BasicModel from rest_framework import generics, routers, serializers, status, viewsets from rest_framework.parsers import JSONParser @@ -11,7 +12,6 @@ ) from rest_framework.response import Response from rest_framework.views import APIView -from tests.models import BasicModel # Serializer used to test BasicModel diff --git a/tests/test_reverse.py b/tests/test_reverse.py index 0962efaf3b..03d31f1f93 100644 --- a/tests/test_reverse.py +++ b/tests/test_reverse.py @@ -2,7 +2,7 @@ from django.conf.urls import url from django.core.urlresolvers import NoReverseMatch -from django.test import override_settings, TestCase +from django.test import TestCase, override_settings from rest_framework.reverse import reverse from rest_framework.test import APIRequestFactory diff --git a/tests/test_routers.py b/tests/test_routers.py index ae46708020..acab660d8b 100644 --- a/tests/test_routers.py +++ b/tests/test_routers.py @@ -5,7 +5,7 @@ from django.conf.urls import include, url from django.core.exceptions import ImproperlyConfigured from django.db import models -from django.test import override_settings, TestCase +from django.test import TestCase, override_settings from rest_framework import permissions, serializers, viewsets from rest_framework.decorators import detail_route, list_route diff --git a/tests/test_testing.py b/tests/test_testing.py index 4fd20c33b7..e6c8de22d4 100644 --- a/tests/test_testing.py +++ b/tests/test_testing.py @@ -6,7 +6,7 @@ from django.conf.urls import url from django.contrib.auth.models import User from django.shortcuts import redirect -from django.test import override_settings, TestCase +from django.test import TestCase, override_settings from rest_framework.decorators import api_view from rest_framework.response import Response diff --git a/tests/test_utils.py b/tests/test_utils.py index adb735511f..70ba7644a1 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -2,14 +2,14 @@ from django.conf.urls import url from django.core.exceptions import ImproperlyConfigured -from django.test import override_settings, TestCase +from django.test import TestCase, override_settings from django.utils import six +from tests.models import BasicModel import rest_framework.utils.model_meta from rest_framework.utils.breadcrumbs import get_breadcrumbs from rest_framework.utils.model_meta import _resolve_model from rest_framework.views import APIView -from tests.models import BasicModel class Root(APIView): From 7ece6338313925d0ef673c09e408d7bc302b832c Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Wed, 1 Jun 2016 13:57:27 +0100 Subject: [PATCH 10/14] Remove unused TEMPLATE_LOADERS setting, in favor of TEMPLATES. --- tests/conftest.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index f7b3d83869..d04ccbf3d6 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -3,18 +3,18 @@ def pytest_configure(): settings.configure( DEBUG_PROPAGATE_EXCEPTIONS=True, - DATABASES={'default': {'ENGINE': 'django.db.backends.sqlite3', - 'NAME': ':memory:'}}, + DATABASES={ + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': ':memory:' + } + }, SITE_ID=1, SECRET_KEY='not very secret in tests', USE_I18N=True, USE_L10N=True, STATIC_URL='/static/', ROOT_URLCONF='tests.urls', - TEMPLATE_LOADERS=( - 'django.template.loaders.filesystem.Loader', - 'django.template.loaders.app_directories.Loader', - ), TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', @@ -33,7 +33,6 @@ def pytest_configure(): 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.staticfiles', - 'rest_framework', 'rest_framework.authtoken', 'tests', From 0ab1aeb9ab1c4136155f6bf184a6bae259ebf3a8 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Wed, 1 Jun 2016 14:01:00 +0100 Subject: [PATCH 11/14] Remove code style issue --- tests/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index d04ccbf3d6..a5123b9d8d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -15,7 +15,7 @@ def pytest_configure(): USE_L10N=True, STATIC_URL='/static/', ROOT_URLCONF='tests.urls', - TEMPLATES = [ + TEMPLATES=[ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'APP_DIRS': True, From b5931940e1abc2ea186f85b57624b112837947b3 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Wed, 1 Jun 2016 14:48:22 +0100 Subject: [PATCH 12/14] BaseFilter test requires a concrete model --- tests/models.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/models.py b/tests/models.py index cde5f8cda2..85143566ee 100644 --- a/tests/models.py +++ b/tests/models.py @@ -27,9 +27,6 @@ class BasicModel(RESTFrameworkModel): class BaseFilterableItem(RESTFrameworkModel): text = models.CharField(max_length=100) - class Meta: - abstract = True - class FilterableItem(BaseFilterableItem): decimal = models.DecimalField(max_digits=4, decimal_places=2) From 3bdbfdb2000860d7dcdc016ca009d312ea41e23f Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Wed, 1 Jun 2016 15:07:41 +0100 Subject: [PATCH 13/14] Resolve tox.ini issues --- tox.ini | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tox.ini b/tox.ini index 15442991e3..ba500a2a03 100644 --- a/tox.ini +++ b/tox.ini @@ -5,8 +5,8 @@ addopts=--tb=short envlist = py27-{lint,docs}, {py27,py32,py33,py34,py35}-django18, - {py27,py34,py35}-django{19} - {py27,py34,py35}-django{110} + {py27,py34,py35}-django19, + {py27,py34,py35}-django110 [testenv] commands = ./runtests.py --fast {posargs} --coverage -rw @@ -19,6 +19,12 @@ deps = django110: Django==1.10a1 -rrequirements/requirements-testing.txt -rrequirements/requirements-optionals.txt +basepython = + py35: python3.5 + py34: python3.4 + py33: python3.3 + py32: python3.2 + py27: python2.7 [testenv:py27-lint] commands = ./runtests.py --lintonly From 3a808a03d63d910cb68afa29a94f9a9b17c2f7eb Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Wed, 1 Jun 2016 15:14:58 +0100 Subject: [PATCH 14/14] Resolve isort differences between local and tox environments --- runtests.py | 2 +- tests/test_atomic_requests.py | 2 +- tests/test_generics.py | 6 +++--- tests/test_multitable_inheritance.py | 2 +- tests/test_permissions.py | 2 +- tests/test_relations_hyperlink.py | 6 +++--- tests/test_relations_pk.py | 4 ++-- tests/test_relations_slug.py | 4 ++-- tests/test_response.py | 2 +- tests/test_utils.py | 2 +- 10 files changed, 16 insertions(+), 16 deletions(-) diff --git a/runtests.py b/runtests.py index a7e8b45a98..1627e33b2c 100755 --- a/runtests.py +++ b/runtests.py @@ -14,7 +14,7 @@ FLAKE8_ARGS = ['rest_framework', 'tests', '--ignore=E501'] -ISORT_ARGS = ['--recursive', '--check-only', 'rest_framework', 'tests'] +ISORT_ARGS = ['--recursive', '--check-only', '-p', 'tests', 'rest_framework', 'tests'] sys.path.append(os.path.dirname(__file__)) diff --git a/tests/test_atomic_requests.py b/tests/test_atomic_requests.py index 3e1d41725f..8342ad3aff 100644 --- a/tests/test_atomic_requests.py +++ b/tests/test_atomic_requests.py @@ -7,13 +7,13 @@ from django.http import Http404 from django.test import TestCase, TransactionTestCase from django.utils.decorators import method_decorator -from tests.models import BasicModel from rest_framework import status from rest_framework.exceptions import APIException from rest_framework.response import Response from rest_framework.test import APIRequestFactory from rest_framework.views import APIView +from tests.models import BasicModel factory = APIRequestFactory() diff --git a/tests/test_generics.py b/tests/test_generics.py index b81a02fc3b..2e47df50fb 100644 --- a/tests/test_generics.py +++ b/tests/test_generics.py @@ -5,13 +5,13 @@ from django.shortcuts import get_object_or_404 from django.test import TestCase from django.utils import six -from tests.models import ( - BasicModel, ForeignKeySource, ForeignKeyTarget, RESTFrameworkModel -) from rest_framework import generics, renderers, serializers, status from rest_framework.response import Response from rest_framework.test import APIRequestFactory +from tests.models import ( + BasicModel, ForeignKeySource, ForeignKeyTarget, RESTFrameworkModel +) factory = APIRequestFactory() diff --git a/tests/test_multitable_inheritance.py b/tests/test_multitable_inheritance.py index 5867f19665..340d4966a5 100644 --- a/tests/test_multitable_inheritance.py +++ b/tests/test_multitable_inheritance.py @@ -2,9 +2,9 @@ from django.db import models from django.test import TestCase -from tests.models import RESTFrameworkModel from rest_framework import serializers +from tests.models import RESTFrameworkModel # Models diff --git a/tests/test_permissions.py b/tests/test_permissions.py index f36b8f4dac..e04c72ec97 100644 --- a/tests/test_permissions.py +++ b/tests/test_permissions.py @@ -7,7 +7,6 @@ from django.core.urlresolvers import ResolverMatch from django.db import models from django.test import TestCase -from tests.models import BasicModel from rest_framework import ( HTTP_HEADER_ENCODING, authentication, generics, permissions, serializers, @@ -17,6 +16,7 @@ from rest_framework.filters import DjangoObjectPermissionsFilter from rest_framework.routers import DefaultRouter from rest_framework.test import APIRequestFactory +from tests.models import BasicModel factory = APIRequestFactory() diff --git a/tests/test_relations_hyperlink.py b/tests/test_relations_hyperlink.py index 27e1d14493..05d8689a34 100644 --- a/tests/test_relations_hyperlink.py +++ b/tests/test_relations_hyperlink.py @@ -2,14 +2,14 @@ from django.conf.urls import url from django.test import TestCase, override_settings + +from rest_framework import serializers +from rest_framework.test import APIRequestFactory from tests.models import ( ForeignKeySource, ForeignKeyTarget, ManyToManySource, ManyToManyTarget, NullableForeignKeySource, NullableOneToOneSource, OneToOneTarget ) -from rest_framework import serializers -from rest_framework.test import APIRequestFactory - factory = APIRequestFactory() request = factory.get('/') # Just to ensure we have a request in the serializer context diff --git a/tests/test_relations_pk.py b/tests/test_relations_pk.py index c82188ede8..ba75bd94fe 100644 --- a/tests/test_relations_pk.py +++ b/tests/test_relations_pk.py @@ -2,14 +2,14 @@ from django.test import TestCase from django.utils import six + +from rest_framework import serializers from tests.models import ( ForeignKeySource, ForeignKeyTarget, ManyToManySource, ManyToManyTarget, NullableForeignKeySource, NullableOneToOneSource, NullableUUIDForeignKeySource, OneToOneTarget, UUIDForeignKeyTarget ) -from rest_framework import serializers - # ManyToMany class ManyToManyTargetSerializer(serializers.ModelSerializer): diff --git a/tests/test_relations_slug.py b/tests/test_relations_slug.py index cee18031d3..680aee4173 100644 --- a/tests/test_relations_slug.py +++ b/tests/test_relations_slug.py @@ -1,10 +1,10 @@ from django.test import TestCase + +from rest_framework import serializers from tests.models import ( ForeignKeySource, ForeignKeyTarget, NullableForeignKeySource ) -from rest_framework import serializers - class ForeignKeyTargetSerializer(serializers.ModelSerializer): sources = serializers.SlugRelatedField( diff --git a/tests/test_response.py b/tests/test_response.py index 28ea90ce4e..c8ae6475ae 100644 --- a/tests/test_response.py +++ b/tests/test_response.py @@ -3,7 +3,6 @@ from django.conf.urls import include, url from django.test import TestCase, override_settings from django.utils import six -from tests.models import BasicModel from rest_framework import generics, routers, serializers, status, viewsets from rest_framework.parsers import JSONParser @@ -12,6 +11,7 @@ ) from rest_framework.response import Response from rest_framework.views import APIView +from tests.models import BasicModel # Serializer used to test BasicModel diff --git a/tests/test_utils.py b/tests/test_utils.py index 70ba7644a1..cd6a6af9a4 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -4,12 +4,12 @@ from django.core.exceptions import ImproperlyConfigured from django.test import TestCase, override_settings from django.utils import six -from tests.models import BasicModel import rest_framework.utils.model_meta from rest_framework.utils.breadcrumbs import get_breadcrumbs from rest_framework.utils.model_meta import _resolve_model from rest_framework.views import APIView +from tests.models import BasicModel class Root(APIView):