Skip to content

Commit

Permalink
Update to Django 4.2 (#1004)
Browse files Browse the repository at this point in the history
* Migration to Django 4.2

* Migration to Django 4.2

* Update README

* Update requirements.txt

* Update requirements.txt

* Fix ALLOWED_HOSTS

* Update requirements.txt: update django-model-utils at version 4.5.1

* Fix requires_system_checks Command property in 'set_passwords' command.

* Update to pyscopg3

* Update PostgreSQL to v16 for CI

* Typo

* Update docker compose for CI

* Fix db name according to ne PG 16

* Deepcopy fix

* Update requirements.txt

* Update README

* Refactoring tests and utilities for Django 4.2

* Change url for proxy test

* Update project version for test

* Fix for test

* Move test data from setUpTestData classmethod to setUp method.

* Fix test for Django 4.2

* Fix test for Django 4.2

* Fix tests for Django 4.2

* Typo

* Fix Test for Django 4.2

* Mismatching datasource path with layers data path inside teh QGIS project file.

* Remove old reference

* Fix tests for Django 4.2

* Fix test for Django 4.2

* Fix tests for Django 4.2

* Restore cassetes to no zipped content

* Update Django to 4.2.17

* Update base version

* Remove old project for test

---------

Co-authored-by: wlorenzetti <[email protected]>
  • Loading branch information
wlorenzetti and wlorenzetti authored Jan 15, 2025
1 parent c645cc5 commit d195a6e
Show file tree
Hide file tree
Showing 56 changed files with 2,710 additions and 1,997 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ Software releases follow theese main branches as described in the compatibility

| Branch | Python | Django | QGIS | [client] | First release | Status |
|------------|--------|----------------|---------------|--------------|---------------|----------------|
| [dev] | 3.12 | 3.2 | 3.34 | dev | Unreleased | ⚠️️ Unstable |
| [v.3.9.x] | 3.10 | 3.2 | 3.34 | 3.11.0 | Jan 2025 | New release |
| [dev] | 3.12 | 4.2 | 3.34 | dev | Unreleased | ⚠️️ Unstable |
| [v.3.9.x] | 3.12 | 4.2 | 3.34 | 3.11.0 | Jan 2025 | New release |
| [v.3.8.x] | 3.10 | 3.2 | 3.34 | 3.10.3 | Sep 2024 | 🪲️ Bug fixing |
| [v.3.7.x] | 3.10 | 3.2 | 3.34 | 3.9.6 | Dec 2023 | 🪲️ Bug fixing |
| [v.3.6.x] | 3.10 | 3.2 | 3.28 | 3.8.15 | May 2023 | 🚨 End of Life |
Expand All @@ -29,6 +29,7 @@ Software releases follow theese main branches as described in the compatibility
| [dj22-py3] | 3.6 | 2.2 | [🔗] | | | 🚨 End of Life |
| [py2] | 2.7 | 1.11 | [🔗] | | | 🚨 End of Life |


[dev]: https://github.com/g3w-suite/g3w-admin/tree/dev
[v.3.8.x]: https://github.com/g3w-suite/g3w-admin/tree/v.3.8.x
[v.3.7.x]: https://github.com/g3w-suite/g3w-admin/tree/v.3.7.x
Expand Down
7 changes: 5 additions & 2 deletions docker-compose.latest.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
# Use QGIS latest release
services:
postgis:
image: g3wsuite/postgis:11.0-2.5
image: kartoza/postgis:16-3.4
ports:
- "55432:5432"
environment:
POSTGRES_USER: docker
POSTGRES_PASS: docker
POSTGRES_DBNAME: g3w-suite
POSTGRES_DBNAME: g3w_suite
ALLOW_IP_RANGE: 0.0.0.0/0
RUN_AS_ROOT: true
FORCE_SSL: False
volumes:
- shared-volume:/shared-volume

Expand Down
9 changes: 6 additions & 3 deletions docker-compose.ltr.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
services:
postgis:
image: g3wsuite/postgis:11.0-2.5
image: kartoza/postgis:16-3.4
ports:
- "55432:5432"
- "55432:5432"
environment:
POSTGRES_USER: docker
POSTGRES_PASS: docker
POSTGRES_DBNAME: g3w-suite
POSTGRES_DBNAME: g3w_suite
ALLOW_IP_RANGE: 0.0.0.0/0
RUN_AS_ROOT: true
FORCE_SSL: False
volumes:
- shared-volume:/shared-volume

Expand Down
86 changes: 42 additions & 44 deletions g3w-admin/about/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,87 +50,85 @@ class AboutTestsBase(TestCase):
'G3WGeneralDataSuite.json',
]

@classmethod
def setUpTestData(cls):
def setUp(self):

translation.activate(settings.LANGUAGE_CODE[:2])

# Admin level 1
cls.test_user_admin1 = User.objects.create_user(username='admin01', password='admin01')
cls.test_user_admin1.is_superuser = True
cls.test_user_admin1.save()
self.test_user_admin1 = User.objects.create_user(username='admin01', password='admin01')
self.test_user_admin1.is_superuser = True
self.test_user_admin1.save()

# Editor level 1
cls.test_user1 = User.objects.create_user(username='user01', password='user01')
cls.group = UserGroup.objects.get(name='Editor Level 1')
cls.test_user1.groups.add(cls.group)
cls.test_user1.save()
self.test_user1 = User.objects.create_user(username='user01', password='user01')
self.group = UserGroup.objects.get(name='Editor Level 1')
self.test_user1.groups.add(self.group)
self.test_user1.save()

# Editor level 2
cls.test_user2 = User.objects.create_user(username='user02', password='user02')
cls.group = UserGroup.objects.get(name='Editor Level 2')
cls.test_user2.groups.add(cls.group)
cls.test_user2.save()
self.test_user2 = User.objects.create_user(username='user02', password='user02')
self.group = UserGroup.objects.get(name='Editor Level 2')
self.test_user2.groups.add(self.group)
self.test_user2.save()

cls.test_user3 = User.objects.create_user(username='user03', password='user03')
cls.group = UserGroup.objects.get(name='Viewer Level 1')
cls.test_user3.groups.add(cls.group)
cls.test_user3.save()
self.test_user3 = User.objects.create_user(username='user03', password='user03')
self.group = UserGroup.objects.get(name='Viewer Level 1')
self.test_user3.groups.add(self.group)
self.test_user3.save()

cls.test_user4 = User.objects.create_user(username='user04', password='user04')
cls.test_user4.groups.add(cls.group)
cls.test_user4.save()
self.test_user4 = User.objects.create_user(username='user04', password='user04')
self.test_user4.groups.add(self.group)
self.test_user4.save()

cls.project_group = CoreGroup(name='Group1', title='Group1', header_logo_img='',
self.project_group = CoreGroup(name='Group1', title='Group1', header_logo_img='',
srid=G3WSpatialRefSys.objects.get(auth_srid=4326))

cls.project_group.save()
cls.project_group.addPermissionsToEditor(cls.test_user2)
self.project_group.save()
self.project_group.addPermissionsToEditor(self.test_user2)

cls.project_group2 = CoreGroup(name='Group2', title='Group2', header_logo_img='',
self.project_group2 = CoreGroup(name='Group2', title='Group2', header_logo_img='',
srid=G3WSpatialRefSys.objects.get(auth_srid=4326))

cls.project_group2.save()
self.project_group2.save()

cls.project_group3 = CoreGroup(name='Group3', title='Group3', header_logo_img='',
self.project_group3 = CoreGroup(name='Group3', title='Group3', header_logo_img='',
srid=G3WSpatialRefSys.objects.get(auth_srid=3857))

cls.project_group3.save()
self.project_group3.save()

# create macrogroups
cls.macrogroup = MacroGroup(title='Macrogroup1', logo_img='macrogroup.png')
cls.macrogroup.save()
cls.project_group2.macrogroups.add(cls.macrogroup)
cls.project_group.macrogroups.add(cls.macrogroup)
self.macrogroup = MacroGroup(title='Macrogroup1', logo_img='macrogroup.png')
self.macrogroup.save()
self.project_group2.macrogroups.add(self.macrogroup)
self.project_group.macrogroups.add(self.macrogroup)

# create macrogroups 2
cls.macrogroup2 = MacroGroup(title='Macrogroup2', logo_img='macrogroup2.png')
cls.macrogroup2.save()
cls.project_group.macrogroups.add(cls.macrogroup2)
self.macrogroup2 = MacroGroup(title='Macrogroup2', logo_img='macrogroup2.png')
self.macrogroup2.save()
self.project_group.macrogroups.add(self.macrogroup2)

# add permission to anonymous and viewer
cls.project_group2.addPermissionsToViewers(users_id=[cls.test_user3.pk, get_user_model().get_anonymous().pk])
self.project_group2.addPermissionsToViewers(users_id=[self.test_user3.pk, get_user_model().get_anonymous().pk])

#projects
qgis_project_file = File(open('{}{}{}'.format(CURRENT_PATH, TEST_BASE_PATH, QGS_FILE), 'r'))
cls.project = QgisProject(qgis_project_file)
cls.project.title = 'A project'
cls.project.group = cls.project_group
cls.project.save()
self.project = QgisProject(qgis_project_file)
self.project.title = 'A project'
self.project.group = self.project_group
self.project.save()

# projects
qgis_project_file = File(open('{}{}{}'.format(CURRENT_PATH, TEST_BASE_PATH, QGS_FILE_2), 'r'))
cls.project2 = QgisProject(qgis_project_file)
cls.project2.group = cls.project_group
cls.project2.save()
self.project2 = QgisProject(qgis_project_file)
self.project2.group = self.project_group
self.project2.save()

# add permission to anonumous and viewer
cls.project.instance.addPermissionsToViewers([cls.test_user3.pk])
self.project.instance.addPermissionsToViewers([self.test_user3.pk])

@classmethod
def tearDownClass(cls):
"""Cleanup """
# Cleanup
super(AboutTestsBase, cls).tearDownClass()


Expand Down
2 changes: 1 addition & 1 deletion g3w-admin/base/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@
logger.warning('Celery could not be imported, this might be ok if there are no custom suite modules that require Celery')


__version__ = (3, 8, 0, 'unstable', 0)
__version__ = (3, 9, 0, 'unstable', 0)
2 changes: 1 addition & 1 deletion g3w-admin/base/management/commands/set_passwords.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

class Command(BaseCommand):
help = 'DEBUG only: sets all user passwords to a common value ("%s" by default)' % (DEFAULT_FAKE_PASSWORD, )
requires_system_checks = False
requires_system_checks = []

def add_arguments(self, parser):
super(Command, self).add_arguments(parser)
Expand Down
3 changes: 2 additions & 1 deletion g3w-admin/base/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
'model_utils',
'formtools',
'crispy_forms',
'crispy_bootstrap3',
'guardian',
'sitetree',
'django_extensions',
Expand Down Expand Up @@ -172,6 +173,7 @@

GUARDIAN_RAISE_403 = True

CRISPY_ALLOWED_TEMPLATE_PACKS = "bootstrap3"
CRISPY_TEMPLATE_PACK = 'bootstrap3'

SITETREE_MODEL_TREE = 'core.G3W2Tree'
Expand All @@ -194,7 +196,6 @@

USE_I18N = True

USE_L10N = True

USE_TZ = False

Expand Down
2 changes: 1 addition & 1 deletion g3w-admin/caching/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from django.http import HttpResponse, JsonResponse
from django.db import transaction
from django.urls import reverse
from django.utils.translation import ugettext as _
from django.utils.translation import gettext_lazy as _
from django.utils.decorators import method_decorator
import TileStache
from rest_framework.views import APIView
Expand Down
1 change: 0 additions & 1 deletion g3w-admin/core/api/base/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from django.core.exceptions import PermissionDenied
from django.http import Http404, HttpRequest
from django.urls import resolve, reverse
from django.utils.translation import ugettext
from django.utils.translation import gettext_lazy as _
from qgis.core import (
QgsJsonExporter,
Expand Down
2 changes: 1 addition & 1 deletion g3w-admin/core/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from django.forms.fields import CharField, HiddenInput
from django.forms.models import ModelMultipleChoiceField, ModelChoiceField
from django.db.models import Q
from django.utils.translation import ugettext, gettext_lazy as _
from django.utils.translation import gettext_lazy as _
from core.models import Group, GeneralSuiteData, MacroGroup
from django_file_form.forms import FileFormMixin
from django.contrib.auth.models import User, Group as AuthGroup
Expand Down
5 changes: 3 additions & 2 deletions g3w-admin/core/mixins/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from django.shortcuts import get_object_or_404
from core.models import Group
from core.utils import file_path_mime
from core.utils.request import is_ajax
import os


Expand Down Expand Up @@ -112,7 +113,7 @@ class AjaxableFormResponseMixin(object):
"""
def form_invalid(self, form):
response = super(AjaxableFormResponseMixin, self).form_invalid(form)
if self.request.is_ajax():
if is_ajax(self.request):
return JsonResponse({'status':'error', 'errors_form': form.errors})
else:
return response
Expand All @@ -122,7 +123,7 @@ def form_valid(self, form):
# it might do some processing (in the case of CreateView, it will
# call form.save() for example).
response = super(AjaxableFormResponseMixin, self).form_valid(form)
if self.request.is_ajax():
if is_ajax(self.request):
return JsonResponse({'status': 'ok', 'message': 'Object saved!'})
else:
return response
Expand Down
12 changes: 7 additions & 5 deletions g3w-admin/core/models.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@

from django.conf import settings
from django.conf.global_settings import LANGUAGES
from django.utils.translation import ugettext, gettext_lazy as _
from django.utils.translation import gettext_lazy as _
from django.urls import reverse
from django.db import models
from django.apps import apps
from django_extensions.db.fields import AutoSlugField
from guardian.shortcuts import get_objects_for_user
from guardian.compat import get_user_model
from ordered_model.models import OrderedModel
from model_utils.models import TimeStampedModel
from model_utils import Choices
from django_extensions.db.fields import AutoSlugField
from sitetree.models import TreeItemBase, TreeBase
from django.contrib.auth.models import User, Group as AuthGroup
Expand Down Expand Up @@ -124,6 +121,9 @@ def remove_permissions_to_editors(self, users_id):
"""
self._permissions_to_editors(users_id, 'remove')

class Meta():
ordering = ("order",)


class Group(TimeStampedModel, OrderedModel):
"""A group of projects."""
Expand Down Expand Up @@ -169,10 +169,12 @@ class Group(TimeStampedModel, OrderedModel):
'as client logo, if MacroGroup option is active this options takes '
'precendence'))

class Meta:
class Meta():
permissions = (
('add_project_to_group', 'Can add project to the group'),
)
ordering = ("order",)


def __str__(self):
return self.name
Expand Down
Loading

0 comments on commit d195a6e

Please sign in to comment.