Skip to content

Commit 48965cb

Browse files
authored
[deps] Added support for Django 5.x #439
- Added support for Python 3.11, 3.12 and 3.13 - Dropped support for Django 3.2 - Dropped support for Python 3.8 - [tests] Added logout helper method in SeleniumTestMixin [theme] Updated CSS to support Django 5.x: - Added border to the inline admin heading (I removed them in OpenWISP) - Changed HTML elements for FilteredMultiSelect widget (widget for adding group/permission to the user) - Added a button for resetting password of the user Closes #439
1 parent 581c1ca commit 48965cb

File tree

9 files changed

+82
-28
lines changed

9 files changed

+82
-28
lines changed

.github/workflows/ci.yml

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,29 @@ jobs:
2020
fail-fast: false
2121
matrix:
2222
python-version:
23-
- "3.8"
2423
- "3.9"
2524
- "3.10"
25+
- "3.11"
26+
- "3.12"
27+
- "3.13"
2628
django-version:
27-
- django~=3.2.0
28-
- django~=4.1.0
2929
- django~=4.2.0
30+
- django~=5.0.0
31+
- django~=5.1.0
32+
- django~=5.2rc0
33+
exclude:
34+
# Django 5.0+ requires Python >=3.10
35+
- python-version: "3.9"
36+
django-version: django~=5.0.0
37+
- python-version: "3.9"
38+
django-version: django~=5.1.0
39+
- python-version: "3.9"
40+
django-version: django~=5.2rc0
41+
# Python 3.13 supported only in Django >=5.1.3
42+
- python-version: "3.13"
43+
django-version: django~=4.2.0
44+
- python-version: "3.13"
45+
django-version: django~=5.0.0
3046

3147
steps:
3248
- uses: actions/checkout@v4

docs/developer/other-utilities.rst

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,12 +86,19 @@ Adds support for excluding file types using
8686
:ref:`OPENWISP_STATICFILES_VERSIONED_EXCLUDE
8787
<openwisp_staticfiles_versioned_exclude>` setting.
8888

89-
To use point ``STATICFILES_STORAGE`` to
89+
To use point ``STORAGES["staticfiles"]`` to
9090
``openwisp_utils.storage.CompressStaticFilesStorage`` in ``settings.py``.
9191

9292
.. code-block:: python
9393
94-
STATICFILES_STORAGE = "openwisp_utils.storage.CompressStaticFilesStorage"
94+
STORAGES = {
95+
"default": {
96+
"BACKEND": "django.core.files.storage.FileSystemStorage",
97+
},
98+
"staticfiles": {
99+
"BACKEND": "openwisp_utils.storage.CompressStaticFilesStorage",
100+
},
101+
}
95102
96103
Other Utilities
97104
---------------

openwisp_utils/admin_theme/static/admin/css/openwisp.css

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ See https://code.djangoproject.com/ticket/33878 */
8080
body {
8181
min-width: 320px;
8282
}
83+
th {
84+
font-weight: 600;
85+
}
8386
.menu-backdrop {
8487
position: fixed;
8588
height: 100vh;
@@ -154,7 +157,9 @@ a.section:visited:focus,
154157
.module h2,
155158
.module caption,
156159
.inline-group h2,
157-
fieldset.module h2 {
160+
fieldset.module h2,
161+
.selector .selector-available-title,
162+
.selector .selector-chosen-title {
158163
background: #f9f9f9;
159164
color: #333;
160165
padding: 15px;
@@ -210,9 +215,15 @@ a:focus {
210215
.module caption,
211216
.inline-group h2,
212217
#content-related h3,
218+
#main .aligned .selector-available-title label,
219+
#main .aligned .selector-chosen-title label,
213220
fieldset.module h2 {
214221
font-size: 16px;
215222
}
223+
#content fieldset .fieldset-heading,
224+
#content fieldset .inline-heading {
225+
border: 0px;
226+
}
216227
#main .inline-related h3 {
217228
padding: 15px;
218229
font-size: 15px;
@@ -433,7 +444,8 @@ div.breadcrumbs {
433444
#main-content div.breadcrumbs {
434445
padding: 1rem 2.5rem;
435446
}
436-
#main .selector-chosen h2 {
447+
#main .selector-chosen h2,
448+
#main .aligned .selector-chosen-title {
437449
background: rgba(0, 0, 0, 0.6);
438450
color: #fff;
439451
}
@@ -746,7 +758,8 @@ input[type="button"]:hover,
746758
}
747759
.account-button:hover span,
748760
.account-button:focus span,
749-
.account-menu a:hover span {
761+
.account-menu .dropdown-clickable:hover span,
762+
.account-menu .dropdown-clickable:focus span {
750763
background: #df5d43;
751764
}
752765
.account-menu {
@@ -797,19 +810,28 @@ input[type="button"]:hover,
797810
display: none;
798811
color: #777;
799812
}
800-
#header .account-menu a {
801-
color: #777;
813+
#header .account-menu .dropdown-clickable {
802814
display: flex;
803-
font-weight: 700;
804815
padding: 0.375rem;
816+
color: #777;
817+
font-weight: 700;
805818
text-decoration: none;
806819
line-height: 22px;
807820
}
821+
#header .account-menu #logout-form button {
822+
text-transform: inherit;
823+
font-size: inherit;
824+
letter-spacing: inherit;
825+
outline: revert;
826+
width: 100%;
827+
}
808828
#header .account-menu li:last-child {
809829
border-bottom: 0;
810830
}
811831
.account-menu-username:hover,
812-
#header .account-menu a:hover {
832+
#header .account-menu .dropdown-clickable:hover,
833+
#header .account-menu .dropdown-clickable:active,
834+
#header .account-menu .dropdown-clickable:focus {
813835
color: #df5d43;
814836
}
815837
#main-content #header {
@@ -832,7 +854,7 @@ input[type="button"]:hover,
832854
#content-main .object-tools {
833855
display: none;
834856
}
835-
#content-main .form-row a:link {
857+
#content-main .form-row a:link:not(.button) {
836858
text-decoration: underline;
837859
}
838860
#content-main .form-row a:link:hover,
@@ -1059,6 +1081,15 @@ div.calendar-shortcuts a:hover {
10591081
}
10601082

10611083
/*********** Selector fix ***********/
1084+
.selector-available-title label,
1085+
.selector-chosen-title label {
1086+
float: unset;
1087+
}
1088+
#main .form-row .selector-chosen-title label,
1089+
#container #main .form-row .selector-chosen-title .helptext {
1090+
color: #fff;
1091+
}
1092+
10621093
@media (max-width: 1226px) and (min-width: 1024px) {
10631094
.related-widget-wrapper > a {
10641095
order: 2;

openwisp_utils/admin_theme/templates/admin/base_site.html

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,17 @@ <h1 id="site-name"><a href="{% url 'admin:index' %}">{{ site_header }}</a></h1>
3838
</li>
3939
{% if user.has_usable_password %}
4040
<li>
41-
<a tabindex="-1" href="{% url 'admin:password_change' %}">
41+
<a class="dropdown-clickable" tabindex="-1" href="{% url 'admin:password_change' %}">
4242
<span class="password"></span>
4343
{% trans 'Change password' %}
4444
</a>
4545
</li>
4646
{% endif %}
4747
<li>
48-
<a tabindex="-1" class="menu-link" href="{% url 'admin:logout' %}">
49-
<span class="logout"></span>
50-
{% trans 'Log out' %}
51-
</a>
48+
<form tabindex="-1" id="logout-form" method="post" action="{% url 'admin:logout' %}">
49+
{% csrf_token %}
50+
<button type="submit" class="dropdown-clickable"><span class="logout"></span>{% translate 'Log out' %}</button>
51+
</form>
5252
</li>
5353
</ul>
5454
</div>

openwisp_utils/tests/selenium.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,11 @@ def login(self, username=None, password=None, driver=None):
166166
driver.find_element(by=By.XPATH, value='//input[@type="submit"]').click()
167167
self._wait_until_page_ready(driver=driver)
168168

169+
def logout(self, driver=None):
170+
driver = driver or self.web_driver
171+
self.web_driver.find_element(By.CSS_SELECTOR, '.account-button').click()
172+
self.web_driver.find_element(By.CSS_SELECTOR, '#logout-form button').click()
173+
169174
def find_element(self, by, value, timeout=2, driver=None, wait_for='visibility'):
170175
driver = driver or self.web_driver
171176
method = f'wait_for_{wait_for}'

tests/openwisp2/settings.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@
5050
LANGUAGE_CODE = 'en-us'
5151
TIME_ZONE = 'UTC'
5252
USE_I18N = True
53-
USE_L10N = True
5453
USE_TZ = True
5554
STATIC_URL = '/static/'
5655

tests/test_project/tests/test_selenium.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ def _test_login_and_logout_page(self, is_logged_in=True):
7171
main_content = self._get_main_content()
7272
self.assertEqual(main_content.get_attribute('class'), 'm-0')
7373
# Test login page
74-
self.web_driver.refresh()
74+
self.open(reverse('admin:login'))
7575
self.wait_for_visibility(By.CSS_SELECTOR, self.config['site_name_css_selector'])
7676
hamburger = self._get_hamburger()
7777
logo = self._get_logo()

tests/test_project/tests/test_storage.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ def create_dir(*paths: str):
2121

2222

2323
@override_settings(
24-
STATICFILES_STORAGE='openwisp_utils.storage.CompressStaticFilesStorage',
24+
STORAGES={
25+
'staticfiles': {'BACKEND': 'openwisp_utils.storage.CompressStaticFilesStorage'}
26+
},
2527
STATIC_ROOT=create_dir(settings.BASE_DIR, 'test_storage_dir', 'test_static_root'),
2628
STATICFILES_DIRS=[
2729
create_dir(settings.BASE_DIR, 'test_storage_dir', 'test_staticfiles_dir')

tests/test_project/tests/utils.py

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,6 @@ def _create_admin(self, **kwargs):
4545
opts.update(kwargs)
4646
return self._create_user(**opts)
4747

48-
def logout(self):
49-
account_button = self._get_account_button()
50-
account_button.click()
51-
logout_link = self._get_logout_link()
52-
logout_link.click()
53-
5448
def _get_menu_toggle(self):
5549
return self.web_driver.find_element(By.CSS_SELECTOR, '.menu-toggle')
5650

@@ -115,7 +109,7 @@ def _get_account_dropdown_username(self):
115109
return self.web_driver.find_element(By.CSS_SELECTOR, '.account-menu-username')
116110

117111
def _get_logout_link(self):
118-
return self.web_driver.find_element(By.CSS_SELECTOR, '.menu-link')
112+
return self.web_driver.find_element(By.CSS_SELECTOR, '#logout-form button')
119113

120114
def _get_menu_backdrop(self):
121115
return self.web_driver.find_element(By.CSS_SELECTOR, '.menu-backdrop')

0 commit comments

Comments
 (0)