diff --git a/g3w-admin/core/mixins/views.py b/g3w-admin/core/mixins/views.py index 566a53a45..bf3db1b54 100644 --- a/g3w-admin/core/mixins/views.py +++ b/g3w-admin/core/mixins/views.py @@ -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 @@ -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 @@ -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 diff --git a/g3w-admin/core/utils/request.py b/g3w-admin/core/utils/request.py new file mode 100644 index 000000000..21d5695c4 --- /dev/null +++ b/g3w-admin/core/utils/request.py @@ -0,0 +1,20 @@ +# coding=utf-8 +"""" +Utilities for django request instance +.. note:: This program is free software; you can redistribute it and/or modify + it under the terms of the Mozilla Public License 2.0. + +""" + +__author__ = 'lorenzetti@gis3w.it' +__date__ = '2024-12-30' +__copyright__ = 'Copyright 2015 - 2024, Gis3w' +__license__ = 'MPL 2.0' + +def is_ajax(request): + """ + Check if request is ajax + :param request: django request instance + :return: True if request is ajax, False otherwise + """ + return request.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest' diff --git a/g3w-admin/core/utils/response.py b/g3w-admin/core/utils/response.py index 0204881b6..90bdb9efe 100644 --- a/g3w-admin/core/utils/response.py +++ b/g3w-admin/core/utils/response.py @@ -15,23 +15,4 @@ def send_file(output_filename, content_type, file, attachment=True): :param attachment: True default, to set Content-Disposition http header. :return: Django HttpResponse instance. """ - return FileResponse(open(file, 'rb'), filename=output_filename, as_attachment=attachment) - - -# class G3WFileFormUploadBackend(FileFormUploadBackend): -# """ Extend default upload backend class of django-file-form module """ -# -# def update_filename(self, request, filename, *args, **kwargs): -# """ Update filename to save on host, if an extension exist it is added to new hash name file """ -# -# hh = super().update_filename(request, filename, *args, **kwargs) -# -# # Add file extension: -# ext = os.path.splitext(filename) -# if ext[1]: -# hh += ext[1] -# -# if ext[1][1:].lower() not in settings.G3WFILE_FORM_UPLOAD_FORMATS: -# raise PermissionDenied() -# -# return hh + return FileResponse(open(file, 'rb'), filename=output_filename, as_attachment=attachment) \ No newline at end of file diff --git a/g3w-admin/qdjango/models/messages.py b/g3w-admin/qdjango/models/messages.py index 1dd299bf5..2a8225fb0 100644 --- a/g3w-admin/qdjango/models/messages.py +++ b/g3w-admin/qdjango/models/messages.py @@ -42,5 +42,5 @@ def __str__(self): return self.title class Meta(): - ordering = ("order",) + ordering = ("-order",) diff --git a/g3w-admin/qdjango/tests/data/geodata/qgis_widget_test_data.gpkg b/g3w-admin/qdjango/tests/data/geodata/qgis_widget_test_data.gpkg index 85299a068..d1a0baa3b 100644 Binary files a/g3w-admin/qdjango/tests/data/geodata/qgis_widget_test_data.gpkg and b/g3w-admin/qdjango/tests/data/geodata/qgis_widget_test_data.gpkg differ diff --git a/g3w-admin/qdjango/tests/test_app.py b/g3w-admin/qdjango/tests/test_app.py index c4e6bf691..3217c1412 100644 --- a/g3w-admin/qdjango/tests/test_app.py +++ b/g3w-admin/qdjango/tests/test_app.py @@ -41,8 +41,12 @@ class AppTest(QdjangoTestBase): def setUpTestData(cls): super().setUpTestData() + + # For Django 4.2 inherit setUpTestData is not maintained the file object inside the models + qprj = Project.objects.get(pk=cls.project.instance.pk) + cls.qdjango_project = Project( - qgis_file=cls.project.qgisProjectFile, + qgis_file=qprj.qgis_file, title='Test qdjango project', group=cls.project_group, ) diff --git a/g3w-admin/qdjango/tests/test_embedded_layers.py b/g3w-admin/qdjango/tests/test_embedded_layers.py index 376c718f6..7a4a383f1 100644 --- a/g3w-admin/qdjango/tests/test_embedded_layers.py +++ b/g3w-admin/qdjango/tests/test_embedded_layers.py @@ -140,7 +140,6 @@ def _testApiCallAdmin01(self, view_name, args, kwargs={}): return response def _make_form(self, project_path, instance=None, name=None): - payload = open(project_path, 'rb').read() if name is None: name = os.path.basename(project_path) @@ -199,9 +198,6 @@ def test_form(self, login=True): # Save embedded project form.qgisProject.save(**form.cleaned_data) - # Store temporary file to avoid error on test exit (because the temp file was moved) - open(form.qgisProject.qgisProjectFile.file.name, 'a').close() - # Verify project = Project.objects.get(original_name='embedded_parent.qgs') self.assertIsNotNone(project) @@ -215,9 +211,6 @@ def test_form(self, login=True): # Save the embedded project form.qgisProject.save(**form.cleaned_data) - # Store temporary file to avoid error on test exit (because the temp file was moved) - open(form.qgisProject.qgisProjectFile.file.name, 'a').close() - project = Project.objects.get(original_name='embedded.qgs') self.assertIsNotNone(project) @@ -274,9 +267,6 @@ def test_form(self, login=True): original_name='embedded_parent.qgs') self.assertEqual(parent_project.title, 'parent_new_title') - # Store temporary file to avoid error on test exit (because the temp file was moved) - open(form.qgisProject.qgisProjectFile.file.name, 'a').close() - # Check that the project embedded layer points to the renamed parent file path project = Project.objects.get(original_name='embedded.qgs') self.assertEqual(project.title, 'embedded.qgs') @@ -302,8 +292,6 @@ def test_form(self, login=True): # Update parent with DD form configuration and test both form = self._make_form(self.parent_project_ddform_path, parent_project, 'embedded_parent_ddform.qgs') form.qgisProject.save(**form.cleaned_data) - # Store temporary file to avoid error on test exit (because the temp file was moved) - open(form.qgisProject.qgisProjectFile.file.name, 'a').close() # Check form configuration for both parent and embedded parent_project = Project.objects.get( @@ -342,7 +330,7 @@ def test_embedded_group(self): form.qgisProject.save(**form.cleaned_data) # Store temporary file to avoid error on test exit (because the temp file was moved) - open(form.qgisProject.qgisProjectFile.file.name, 'a').close() + #open(form.qgisProject.qgisProjectFile.file.name, 'a').close() # Verify project = Project.objects.get( @@ -359,10 +347,6 @@ def test_embedded_group(self): # Save the embedded project form.qgisProject.save(**form.cleaned_data) - - # Store temporary file to avoid error on test exit (because the temp file was moved) - open(form.qgisProject.qgisProjectFile.file.name, 'a').close() - project = Project.objects.get(original_name='embedded_group.qgs') self.assertIsNotNone(project) @@ -383,8 +367,6 @@ def test_embedded_group(self): parent_project=Project.objects.get(original_name='embedded_parent_group.qgs') form = self._make_form(self.parent_project_group_path, parent_project, 'embedded_parent_group.qgs') form.qgisProject.save(instance=parent_project, **form.cleaned_data) - # Store temporary file to avoid error on test exit (because the temp file was moved) - open(form.qgisProject.qgisProjectFile.file.name, 'a').close() parent_project=Project.objects.get(original_name='embedded_parent_group.qgs') self.assertEqual(parent_project.layer_set.count(), 3) @@ -398,8 +380,6 @@ def test_embedded_group(self): parent_project=Project.objects.get(original_name='embedded_parent_group.qgs') form = self._make_form(self.parent_project_wms_added, parent_project, 'embedded_parent_group.qgs') form.qgisProject.save(instance=parent_project, **form.cleaned_data) - # Store temporary file to avoid error on test exit (because the temp file was moved) - open(form.qgisProject.qgisProjectFile.file.name, 'a').close() parent_project=Project.objects.get(original_name='embedded_parent_group.qgs') self.assertEqual(parent_project.layer_set.count(), 4) @@ -412,8 +392,7 @@ def test_embedded_group(self): parent_project=Project.objects.get(original_name='embedded_parent_group.qgs') form = self._make_form(self.parent_project_group_path, parent_project, 'embedded_parent_group.qgs') form.qgisProject.save(instance=parent_project, **form.cleaned_data) - # Store temporary file to avoid error on test exit (because the temp file was moved) - open(form.qgisProject.qgisProjectFile.file.name, 'a').close() + self.assertEqual(parent_project.layer_set.count(), 3) project = Project.objects.get(original_name='embedded_group.qgs') self.assertEqual(project.layer_set.count(), 4) diff --git a/g3w-admin/qdjango/tests/test_ows.py b/g3w-admin/qdjango/tests/test_ows.py index a00710c89..257e7c30a 100644 --- a/g3w-admin/qdjango/tests/test_ows.py +++ b/g3w-admin/qdjango/tests/test_ows.py @@ -29,8 +29,14 @@ from qdjango.models import Project, ProjectMapUrlAlias from qgis.core import QgsProject -from .base import (CURRENT_PATH, QGS310_WIDGET_FILE, TEST_BASE_PATH, - QdjangoTestBase, QgisProject) +from .base import ( + CURRENT_PATH, + QGS310_WIDGET_FILE, + TEST_BASE_PATH, + QGS_FILE, + QdjangoTestBase, + QgisProject +) @override_settings(CACHES={ @@ -51,14 +57,11 @@ class OwsTest(QdjangoTestBase): def setUpTestData(cls): super().setUpTestData() - #cls.qdjango_project = Project( - # qgis_file=cls.project.qgisProjectFile, - # title='Test qdjango project', - # group=cls.project_group, - #) - #cls.qdjango_project.save() - - cls.project2 = QgisProject(cls.project.qgisProjectFile) + + # For Django 4.2 inherit setUpTestData is not maintained the file object inside the models + qgis_project_file = File(open('{}{}{}'.format(CURRENT_PATH, TEST_BASE_PATH, QGS_FILE), 'r')) + + cls.project2 = QgisProject(qgis_project_file) cls.project2.title = "Test qdjango project" cls.project2.group = cls.project_group cls.project2.save() @@ -436,7 +439,7 @@ def testLegendOnOffFilter(self): self.assertTrue(c.login(username='admin01', password='admin01')) project = get_qgs_project( - self.project_widget310.qgisProjectFile.file.name) + self.project_widget310.instance.qgis_file.path) main_layer = project.mapLayersByName('main_layer')[0] renderer = main_layer.renderer() items = renderer.legendSymbolItems() @@ -529,7 +532,7 @@ def testLegendOnOffFilter(self): 'project_id': self.project_widget310_off.instance.id}) project = get_qgs_project( - self.project_widget310_off.qgisProjectFile.file.name) + self.project_widget310_off.instance.qgis_file.path) main_layer = project.mapLayersByName('main_layer')[0] renderer = main_layer.renderer() self.assertFalse(renderer.legendSymbolItemChecked(key1)) diff --git a/g3w-admin/qdjango/tests/test_ows_postgres.py b/g3w-admin/qdjango/tests/test_ows_postgres.py index 640ec9e31..8bfd044f0 100644 --- a/g3w-admin/qdjango/tests/test_ows_postgres.py +++ b/g3w-admin/qdjango/tests/test_ows_postgres.py @@ -76,8 +76,11 @@ def setUpTestData(cls): project_path = os.path.join( CURRENT_PATH + TEST_BASE_PATH, 'pg_multiple_pks.qgs') cls.temp_dir = QTemporaryDir() + + # For Djanog 4.2 and initial class serialization + cls.temp_dir_path = cls.temp_dir.path() cls.temp_project_path = os.path.join( - cls.temp_dir.path(), 'pg_multiple_pks.qgs') + cls.temp_dir_path, 'pg_multiple_pks.qgs') # Create test layer conn_str = "host={HOST} port={PORT} dbname={NAME} user={USER} password={PASSWORD}".format( @@ -226,7 +229,7 @@ def test_getPrint(self): self.assertEqual(response.status_code, 200) - result_path = os.path.join(self.temp_dir.path(), 'red.png') + result_path = os.path.join(self.temp_dir_path, 'red.png') with open(result_path, 'wb+') as f: f.write(response.content) @@ -253,7 +256,7 @@ def test_getPrint(self): # Test self.assertEqual(response.status_code, 200) - result_path = os.path.join(self.temp_dir.path(), 'white.png') + result_path = os.path.join(self.temp_dir_path, 'white.png') with open(result_path, 'wb+') as f: f.write(response.content)