Merge "Drop Django <= 1.10 support"
This commit is contained in:
commit
cd06fe813e
@ -54,11 +54,11 @@
|
||||
- project:
|
||||
check:
|
||||
jobs:
|
||||
- horizon-openstack-tox-py35dj20:
|
||||
voting: false
|
||||
- horizon-openstack-tox-py35dj20
|
||||
- horizon-selenium-headless
|
||||
- horizon-dsvm-tempest-plugin
|
||||
gate:
|
||||
jobs:
|
||||
- horizon-openstack-tox-py35dj20
|
||||
- horizon-selenium-headless
|
||||
- horizon-dsvm-tempest-plugin
|
||||
|
@ -27,7 +27,6 @@ import inspect
|
||||
import logging
|
||||
import os
|
||||
|
||||
import django
|
||||
from django.conf import settings
|
||||
from django.conf.urls import include
|
||||
from django.conf.urls import url
|
||||
@ -58,12 +57,7 @@ def _decorate_urlconf(urlpatterns, decorator, *args, **kwargs):
|
||||
for pattern in urlpatterns:
|
||||
if getattr(pattern, 'callback', None):
|
||||
decorated = decorator(pattern.callback, *args, **kwargs)
|
||||
if django.VERSION >= (1, 10):
|
||||
pattern.callback = decorated
|
||||
else:
|
||||
# prior to 1.10 callback was a property and we had
|
||||
# to modify the private attribute behind the property
|
||||
pattern._callback = decorated
|
||||
if getattr(pattern, 'url_patterns', []):
|
||||
_decorate_urlconf(pattern.url_patterns, decorator, *args, **kwargs)
|
||||
|
||||
|
@ -10,15 +10,11 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import django
|
||||
from django import template
|
||||
from django.template import defaultfilters
|
||||
from django.utils import safestring
|
||||
|
||||
if django.VERSION >= (1, 9):
|
||||
register = template.Library()
|
||||
else:
|
||||
register = template.base.Library()
|
||||
|
||||
|
||||
@register.filter(is_safe=True)
|
||||
|
@ -22,7 +22,6 @@ from importlib import import_module
|
||||
import six
|
||||
from six import moves
|
||||
|
||||
import django
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
@ -310,10 +309,7 @@ class HorizonTests(BaseHorizonTests):
|
||||
|
||||
self.client.logout()
|
||||
resp = self.client.get(url)
|
||||
if django.VERSION >= (1, 9):
|
||||
self.assertRedirects(resp, settings.TESTSERVER + redirect_url)
|
||||
else:
|
||||
self.assertRedirects(resp, redirect_url)
|
||||
|
||||
# Set SSL settings for test server
|
||||
settings.SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTOCOL',
|
||||
|
@ -13,7 +13,6 @@
|
||||
|
||||
import uuid
|
||||
|
||||
import django
|
||||
from django.conf import settings
|
||||
from django.contrib import auth
|
||||
from django import test
|
||||
@ -395,10 +394,7 @@ class OpenStackAuthTestsV2(OpenStackAuthTestsMixin, test.TestCase):
|
||||
response = self.client.get(url, form_data)
|
||||
|
||||
if next:
|
||||
if django.VERSION >= (1, 9):
|
||||
expected_url = next
|
||||
else:
|
||||
expected_url = 'http://testserver%s' % next
|
||||
self.assertEqual(response['location'], expected_url)
|
||||
else:
|
||||
self.assertRedirects(response, settings.LOGIN_REDIRECT_URL)
|
||||
@ -444,10 +440,7 @@ class OpenStackAuthTestsV2(OpenStackAuthTestsMixin, test.TestCase):
|
||||
response = self.client.get(url, form_data)
|
||||
|
||||
if next:
|
||||
if django.VERSION >= (1, 9):
|
||||
expected_url = next
|
||||
else:
|
||||
expected_url = 'http://testserver%s' % next
|
||||
self.assertEqual(response['location'], expected_url)
|
||||
else:
|
||||
self.assertRedirects(response, settings.LOGIN_REDIRECT_URL)
|
||||
@ -768,10 +761,7 @@ class OpenStackAuthTestsV3(OpenStackAuthTestsMixin,
|
||||
response = self.client.get(url, form_data)
|
||||
|
||||
if next:
|
||||
if django.VERSION >= (1, 9):
|
||||
expected_url = next
|
||||
else:
|
||||
expected_url = 'http://testserver%s' % next
|
||||
self.assertEqual(response['location'], expected_url)
|
||||
else:
|
||||
self.assertRedirects(response, settings.LOGIN_REDIRECT_URL)
|
||||
@ -816,10 +806,7 @@ class OpenStackAuthTestsV3(OpenStackAuthTestsMixin,
|
||||
response = self.client.get(url, form_data)
|
||||
|
||||
if next:
|
||||
if django.VERSION >= (1, 9):
|
||||
expected_url = next
|
||||
else:
|
||||
expected_url = 'http://testserver%s' % next
|
||||
self.assertEqual(response['location'], expected_url)
|
||||
else:
|
||||
self.assertRedirects(response, settings.LOGIN_REDIRECT_URL)
|
||||
|
@ -17,7 +17,6 @@ import logging
|
||||
import os
|
||||
import unittest
|
||||
|
||||
import django
|
||||
from django import http
|
||||
from django.test.utils import override_settings
|
||||
from django.urls import reverse
|
||||
@ -277,14 +276,9 @@ class CreateProjectWorkflowTests(test.BaseAdminViewTests):
|
||||
res = self.client.get(reverse('horizon:identity:projects:create'))
|
||||
|
||||
self.assertTemplateUsed(res, views.WorkflowView.template_name)
|
||||
if django.VERSION >= (1, 10):
|
||||
pattern = ('<input autocomplete="off" class="form-control" '
|
||||
'id="id_subnet" min="-1" '
|
||||
'name="subnet" type="number" value="10" required/>')
|
||||
else:
|
||||
pattern = ('<input autocomplete="off" class="form-control" '
|
||||
'id="id_subnet" min="-1" '
|
||||
'name="subnet" type="number" value="10"/>')
|
||||
self.assertContains(res, pattern, html=True)
|
||||
|
||||
workflow = res.context['workflow']
|
||||
|
@ -18,7 +18,6 @@
|
||||
|
||||
from socket import timeout as socket_timeout
|
||||
|
||||
import django
|
||||
from django import http
|
||||
from django.test.utils import override_settings
|
||||
from django.urls import reverse
|
||||
@ -238,7 +237,6 @@ class UsersViewTests(test.BaseAdminViewTests):
|
||||
api.keystone.role_list(IgnoreArg()).AndReturn(self.roles.list())
|
||||
api.keystone.get_default_role(IgnoreArg()) \
|
||||
.AndReturn(self.roles.first())
|
||||
if django.VERSION >= (1, 9):
|
||||
if api.keystone.VERSIONS.active >= 3:
|
||||
api.keystone.tenant_list(
|
||||
IgnoreArg(), domain=domain_id).AndReturn(
|
||||
@ -291,7 +289,6 @@ class UsersViewTests(test.BaseAdminViewTests):
|
||||
api.keystone.role_list(IgnoreArg()).AndReturn(self.roles.list())
|
||||
api.keystone.get_default_role(IgnoreArg()) \
|
||||
.AndReturn(self.roles.first())
|
||||
if django.VERSION >= (1, 9):
|
||||
if api.keystone.VERSIONS.active >= 3:
|
||||
api.keystone.tenant_list(
|
||||
IgnoreArg(), domain=domain_id).AndReturn(
|
||||
@ -347,7 +344,6 @@ class UsersViewTests(test.BaseAdminViewTests):
|
||||
api.keystone.role_list(IgnoreArg()).AndReturn(self.roles.list())
|
||||
api.keystone.get_default_role(IgnoreArg()) \
|
||||
.AndReturn(self.roles.first())
|
||||
if django.VERSION >= (1, 9):
|
||||
if api.keystone.VERSIONS.active >= 3:
|
||||
api.keystone.tenant_list(
|
||||
IgnoreArg(), domain=domain_id).AndReturn(
|
||||
|
@ -1783,18 +1783,11 @@ class InstanceTests(helpers.ResetImageAPIVersionMixin, helpers.TestCase):
|
||||
|
||||
# NOTE(adriant): Django 1.11 changes the checked syntax to use html5
|
||||
# "checked" rather than XHTML's "checked='checked'".
|
||||
if django.VERSION >= (1, 11):
|
||||
checked_box = (
|
||||
'<input type="checkbox" name="network" '
|
||||
'value="82288d84-e0a5-42ac-95be-e6af08727e42" '
|
||||
'id="id_network_0" checked />'
|
||||
)
|
||||
else:
|
||||
checked_box = (
|
||||
'<input type="checkbox" name="network" '
|
||||
'value="82288d84-e0a5-42ac-95be-e6af08727e42" '
|
||||
'id="id_network_0" checked="checked" />'
|
||||
)
|
||||
if only_one_network:
|
||||
self.assertContains(res, checked_box, html=True)
|
||||
else:
|
||||
|
@ -13,7 +13,6 @@
|
||||
# under the License.
|
||||
import copy
|
||||
|
||||
import django
|
||||
from django import http
|
||||
from django.urls import reverse
|
||||
|
||||
@ -590,14 +589,9 @@ class RouterActionTests(RouterMixin, test.TestCase):
|
||||
|
||||
self.assertTemplateUsed(res, 'project/routers/update.html')
|
||||
self.assertContains(res, 'Router Type')
|
||||
if django.VERSION >= (1, 10):
|
||||
pattern = ('<input class="form-control" id="id_mode" name="mode" '
|
||||
'readonly="readonly" type="text" value="distributed" '
|
||||
'required/>')
|
||||
else:
|
||||
pattern = ('<input class="form-control" id="id_mode" name="mode" '
|
||||
'readonly="readonly" type="text" '
|
||||
'value="distributed" />')
|
||||
self.assertContains(res, pattern, html=True)
|
||||
self.assertNotContains(res, 'centralized')
|
||||
|
||||
|
@ -21,7 +21,6 @@ import cgi
|
||||
from mox3.mox import IsA
|
||||
import six
|
||||
|
||||
import django
|
||||
from django.conf import settings
|
||||
from django import http
|
||||
from django.urls import reverse
|
||||
@ -478,9 +477,7 @@ class SecurityGroupsViewTests(test.TestCase):
|
||||
sec_group_list = self.security_groups.list()
|
||||
rule = self.security_group_rules.first()
|
||||
|
||||
api.neutron.security_group_list(
|
||||
IsA(http.HttpRequest)).AndReturn(sec_group_list)
|
||||
if django.VERSION >= (1, 9):
|
||||
for i in range(2):
|
||||
api.neutron.security_group_list(
|
||||
IsA(http.HttpRequest)).AndReturn(sec_group_list)
|
||||
|
||||
@ -503,11 +500,7 @@ class SecurityGroupsViewTests(test.TestCase):
|
||||
sec_group_list = self.security_groups.list()
|
||||
rule = self.security_group_rules.first()
|
||||
|
||||
for i in range(3):
|
||||
api.neutron.security_group_list(
|
||||
IsA(http.HttpRequest)).AndReturn(sec_group_list)
|
||||
if django.VERSION >= (1, 9):
|
||||
for i in range(3):
|
||||
for i in range(6):
|
||||
api.neutron.security_group_list(
|
||||
IsA(http.HttpRequest)).AndReturn(sec_group_list)
|
||||
|
||||
@ -559,10 +552,7 @@ class SecurityGroupsViewTests(test.TestCase):
|
||||
icmp_rule = self.security_group_rules.list()[1]
|
||||
|
||||
# Call POST 5 times (*2 if Django >= 1.9)
|
||||
call_post = 5
|
||||
if django.VERSION >= (1, 9):
|
||||
call_post *= 2
|
||||
|
||||
call_post = 5 * 2
|
||||
for i in range(call_post):
|
||||
api.neutron.security_group_list(
|
||||
IsA(http.HttpRequest)).AndReturn(sec_group_list)
|
||||
@ -921,9 +911,7 @@ class SecurityGroupsViewTests(test.TestCase):
|
||||
sec_group_list = self.security_groups.list()
|
||||
rule = self.security_group_rules.first()
|
||||
|
||||
api.neutron.security_group_list(
|
||||
IsA(http.HttpRequest)).AndReturn(sec_group_list)
|
||||
if django.VERSION >= (1, 9):
|
||||
for i in range(2):
|
||||
api.neutron.security_group_list(
|
||||
IsA(http.HttpRequest)).AndReturn(sec_group_list)
|
||||
|
||||
|
@ -17,7 +17,6 @@ import copy
|
||||
import mock
|
||||
import six
|
||||
|
||||
import django
|
||||
from django.conf import settings
|
||||
from django.forms import widgets
|
||||
from django.template.defaultfilters import slugify
|
||||
@ -634,12 +633,8 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
||||
self.assertFormError(res, 'form', None,
|
||||
"The volume size cannot be less than the "
|
||||
"snapshot size (40GiB)")
|
||||
if django.VERSION >= (1, 9):
|
||||
self.assertEqual(3, self.mock_volume_type_list.call_count)
|
||||
self.assertEqual(2, self.mock_volume_type_default.call_count)
|
||||
else:
|
||||
self.assertEqual(2, self.mock_volume_type_list.call_count)
|
||||
self.assertEqual(1, self.mock_volume_type_default.call_count)
|
||||
|
||||
self.mock_volume_snapshot_get.assert_called_with(test.IsHttpRequest(),
|
||||
str(snapshot.id))
|
||||
@ -812,12 +807,8 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
||||
|
||||
self.assertFormError(res, 'form', None, msg)
|
||||
|
||||
if django.VERSION >= (1, 9):
|
||||
self.assertEqual(3, self.mock_volume_type_list.call_count)
|
||||
self.assertEqual(2, self.mock_volume_type_default.call_count)
|
||||
else:
|
||||
self.assertEqual(2, self.mock_volume_type_list.call_count)
|
||||
self.assertEqual(1, self.mock_volume_type_default.call_count)
|
||||
|
||||
self.assertEqual(2, self.mock_tenant_limit_usages.call_count)
|
||||
self.mock_image_get.assert_called_with(test.IsHttpRequest(),
|
||||
@ -861,14 +852,9 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
||||
self.assertFormError(res, 'form', None,
|
||||
"The volume size cannot be less than the "
|
||||
"image minimum disk size (30GiB)")
|
||||
if django.VERSION >= (1, 9):
|
||||
self.assertEqual(3, self.mock_volume_type_list.call_count)
|
||||
self.assertEqual(2, self.mock_volume_type_default.call_count)
|
||||
self.assertEqual(2, self.mock_availability_zone_list.call_count)
|
||||
else:
|
||||
self.assertEqual(2, self.mock_volume_type_list.call_count)
|
||||
self.assertEqual(1, self.mock_volume_type_default.call_count)
|
||||
self.assertEqual(1, self.mock_availability_zone_list.call_count)
|
||||
|
||||
self.mock_image_get.assert_called_with(test.IsHttpRequest(),
|
||||
str(image.id))
|
||||
@ -932,16 +918,10 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
||||
' have 20GiB of your quota available.']
|
||||
self.assertEqual(res.context['form'].errors['__all__'], expected_error)
|
||||
|
||||
if django.VERSION >= (1, 9):
|
||||
self.assertEqual(3, self.mock_volume_type_list.call_count)
|
||||
self.assertEqual(2, self.mock_volume_type_default.call_count)
|
||||
self.assertEqual(2, self.mock_volume_list.call_count)
|
||||
self.assertEqual(2, self.mock_availability_zone_list.call_count)
|
||||
else:
|
||||
self.assertEqual(2, self.mock_volume_type_list.call_count)
|
||||
self.assertEqual(1, self.mock_volume_type_default.call_count)
|
||||
self.assertEqual(1, self.mock_volume_list.call_count)
|
||||
self.assertEqual(1, self.mock_availability_zone_list.call_count)
|
||||
|
||||
self.assertEqual(2, self.mock_tenant_limit_usages.call_count)
|
||||
self.mock_volume_snapshot_list.assert_called_with(
|
||||
@ -993,14 +973,9 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
|
||||
' volumes.']
|
||||
self.assertEqual(res.context['form'].errors['__all__'], expected_error)
|
||||
|
||||
if django.VERSION >= (1, 9):
|
||||
self.assertEqual(3, self.mock_volume_type_list.call_count)
|
||||
self.assertEqual(2, self.mock_volume_type_default.call_count)
|
||||
self.assertEqual(2, self.mock_availability_zone_list.call_count)
|
||||
else:
|
||||
self.assertEqual(2, self.mock_volume_type_list.call_count)
|
||||
self.assertEqual(1, self.mock_volume_type_default.call_count)
|
||||
self.assertEqual(1, self.mock_availability_zone_list.call_count)
|
||||
|
||||
self.mock_volume_snapshot_list.assert_called_with(
|
||||
test.IsHttpRequest(), search_opts=SEARCH_OPTS)
|
||||
|
@ -25,7 +25,6 @@ import os
|
||||
import traceback
|
||||
import unittest
|
||||
|
||||
import django
|
||||
from django.conf import settings
|
||||
from django.contrib.messages.storage import default_storage
|
||||
from django.core.handlers import wsgi
|
||||
@ -342,14 +341,10 @@ class TestCase(horizon_helpers.TestCase):
|
||||
Asserts that the given response issued a 302 redirect without
|
||||
processing the view which is redirected to.
|
||||
"""
|
||||
if django.VERSION >= (1, 9):
|
||||
loc = six.text_type(response._headers.get('location', None)[1])
|
||||
loc = http.urlunquote(loc)
|
||||
expected_url = http.urlunquote(expected_url)
|
||||
self.assertEqual(loc, expected_url)
|
||||
else:
|
||||
self.assertEqual(response._headers.get('location', None),
|
||||
('Location', settings.TESTSERVER + expected_url))
|
||||
self.assertEqual(response.status_code, 302)
|
||||
|
||||
def assertNoFormErrors(self, response, context_name="form"):
|
||||
|
6
releasenotes/notes/django-2.0-b37c6e91d20519fa.yaml
Normal file
6
releasenotes/notes/django-2.0-b37c6e91d20519fa.yaml
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
upgrade:
|
||||
- |
|
||||
Django 2.0 support is added as experimental.
|
||||
Support for Django 1.10 or older releases is dropped.
|
||||
Django 1.11 (LTS) is still the primary supported Django version.
|
Loading…
Reference in New Issue
Block a user