diff --git a/README.md b/README.md index 9a8f1fb16..edf4ec646 100644 --- a/README.md +++ b/README.md @@ -15,16 +15,16 @@ Software releases follow theese main branches as described in the compatibility | Branch | Python | Django | QGIS | [client] | First release | Status | |------------|----------------|----------------|---------------|----------|---------------|----------------| -| [dev] | 3.10 | 3.2 | 3.28 | dev | Unreleased | ⚠️️ Unstable | -| [v.3.6.x] | 3.10 | 3.2 | 3.28 | 3.8.10 | May 2023 | 🪲️ Bug fixing | -| [v.3.5.x] | 3.10 | 2.2 | 3.22 | 3.7 | Nov 2022 | 🪲️ Bug fixing | +| [dev] | 3.10 | 3.2 | 3.28 | dev | Unreleased | ⚠️️ Unstable | +| [v.3.6.x] | 3.10 | 3.2 | 3.28 | 3.8.10 | May 2023 | 🪲️ Bug fixing | +| [v.3.5.x] | 3.10 | 2.2 | 3.22 | 3.7 | Nov 2022 | 🪲️ Bug fixing | | [v.3.4.x] | 3.8 | 2.2 | 3.22 | 3.4 | Mar 2022 | 🚨 End of Life | | [v.3.3.x] | 3.6 | 2.2 | 3.16 | 3.3 | Sep 2021 | 🚨 End of Life | | [v.3.2.x] | 3.6 | 2.2 | 3.16 | 3.2 | Apr 2021 | 🚨 End of Life | | [v.3.1.x] | 3.6 | 2.2 | 3.10 | 3.1 | Nov 2020 | 🚨 End of Life | -| [v.3.0.x] | 3.6 | 2.2 | 3.10 | 3.0 | Nov 2020 | 🚨 End of Life | -| [dj22-py3] | 3.6 | 2.2 | [🔗] | | | 🚨 End of Life | -| [py2] | 2.7 | 1.11 | [🔗] | | | 🚨 End of Life | +| [v.3.0.x] | 3.6 | 2.2 | 3.10 | 3.0 | Nov 2020 | 🚨 End of Life | +| [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.6.x]: https://github.com/g3w-suite/g3w-admin/tree/v.3.6.x diff --git a/g3w-admin/base/__init__.py b/g3w-admin/base/__init__.py index 7df0a5aaf..0d6213723 100644 --- a/g3w-admin/base/__init__.py +++ b/g3w-admin/base/__init__.py @@ -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, 6, 0, 'unstable', 0) +__version__ = (0, 0, 0, 'unstable', 0) diff --git a/g3w-admin/core/utils/structure.py b/g3w-admin/core/utils/structure.py index f4505a663..ee6f2c5d0 100644 --- a/g3w-admin/core/utils/structure.py +++ b/g3w-admin/core/utils/structure.py @@ -96,7 +96,8 @@ def editingFormField(fieldName, type=FIELD_TYPE_STRING, editable=True, required=False, validate=None, - fieldLabel=None, inputType=None, values=None, default_clause='', unique=False, expression='', pk=False, ** kwargs): + fieldLabel=None, inputType=None, values=None, default_clause='', unique=False, expression='', + pk=False, ** kwargs): """ Build editing form field for client. """ @@ -140,7 +141,7 @@ def editingFormField(fieldName, type=FIELD_TYPE_STRING, editable=True, required= def mapLayerAttributes(layer, formField=False, **kwargs): """ - Map database columns data from layer by type for client editing + Map database columns data from layer by type for client """ mappingData = FIELD_TYPES_MAPPING @@ -222,6 +223,22 @@ def mapLayerAttributesFromQgisLayer(qgis_layer, **kwargs): pk_attributes = qgis_layer.primaryKeyAttributes() + # Get available Join's fields + join_fields = {} + for order, join in enumerate(qgis_layer.vectorJoins()): + join_id = f'{qgis_layer.id()}_vectorjoin_{order}' + joinlayer_pk_attributes = join.joinLayer().primaryKeyAttributes() + for i, f in enumerate(join.joinLayer().fields()): + editable = join.isEditable() + + # Check if referencing field is PK + if i in joinlayer_pk_attributes: + editable = False + join_fields[join.prefixedFieldName(f)] = { + 'editable': editable, + 'join_id': join_id} + + # Determine if we are using an old and bugged version of QGIS IS_QGIS_3_10 = Qgis.QGIS_VERSION.startswith('3.10') @@ -282,8 +299,6 @@ def mapLayerAttributesFromQgisLayer(qgis_layer, **kwargs): else: is_pk = (field_index in pk_attributes) - # - toRes[field.name()] = editingFormField( field.name(), required=not_null, @@ -342,6 +357,14 @@ def mapLayerAttributesFromQgisLayer(qgis_layer, **kwargs): toRes[field.name()]['input']['options']['default_expression']['apply_on_update'] = True \ if field.defaultValueDefinition().applyOnUpdate() else False + # Check for Join's field. + # About joins in QGIS control the join settings for editing. + try: + toRes[field.name()]['vectorjoin_id'] = join_fields[field.name()]['join_id'] + toRes[field.name()]["editable"] = join_fields[field.name()]["editable"] + except: + pass + field_index += 1 return toRes diff --git a/g3w-admin/editing/tests/data/api/editing_api_config_cities_54d40b01_2af8_4b17_8495_c5833485536e.json b/g3w-admin/editing/tests/data/api/editing_api_config_cities_54d40b01_2af8_4b17_8495_c5833485536e.json index 3fc05eec1..ee0ee4bd3 100644 --- a/g3w-admin/editing/tests/data/api/editing_api_config_cities_54d40b01_2af8_4b17_8495_c5833485536e.json +++ b/g3w-admin/editing/tests/data/api/editing_api_config_cities_54d40b01_2af8_4b17_8495_c5833485536e.json @@ -1,431 +1,324 @@ { - "result":true, - "vector":{ - "format":"GeoJSON", - "count":null, - "data":null, - "geometrytype":"Point", - "fields":[ - { - "name":"ogc_fid", - "type":"bigint", - "label":"ogc_fid", - "editable":false, - "validate":{ - "required":true, - "unique":true - }, - "pk":true, - "default":"Autogenerate", - "input":{ - "type":"text", - "options":{ - - } - } - }, - { - "name":"geonameid", - "type":"bigint", - "label":"geonameid", - "editable":true, - "validate":{ - - }, - "pk":false, - "default":"", - "input":{ - "type":"text", - "options":{ - - } - } - }, - { - "name":"name", - "type":"varchar", - "label":"name", - "editable":true, - "validate":{ - - }, - "pk":false, - "default":"", - "input":{ - "type":"text", - "options":{ - - } - } - }, - { - "name":"asciiname", - "type":"varchar", - "label":"asciiname", - "editable":true, - "validate":{ - - }, - "pk":false, - "default":"", - "input":{ - "type":"text", - "options":{ - - } - } - }, - { - "name":"iso2_code", - "type":"varchar", - "label":"iso2_code", - "editable":true, - "validate":{ - - }, - "pk":false, - "default":"", - "input":{ - "type":"text", - "options":{ - - } - } - }, - { - "name":"population", - "type":"bigint", - "label":"population", - "editable":true, - "validate":{ - - }, - "pk":false, - "default":"", - "input":{ - "type":"text", - "options":{ - - } - } - }, - { - "name":"gtopo30", - "type":"bigint", - "label":"gtopo30", - "editable":true, - "validate":{ - - }, - "pk":false, - "default":"", - "input":{ - "type":"text", - "options":{ - - } - } - }, - { - "name":"countries_ogc_fid", - "type":"bigint", - "label":"countries_ogc_fid", - "editable":false, - "validate":{ - "required":true, - "unique":true - }, - "pk":"", - "default":"", - "input":{ - "type":"text", - "options":{ - - } - } - }, - { - "name":"countries_name_local", - "type":"varchar", - "label":"countries_name_local", - "editable":false, - "validate":{ - - }, - "pk":false, - "default":"", - "input":{ - "type":"text", - "options":{ - - } - } - }, - { - "name":"countries_name_en", - "type":"varchar", - "label":"countries_name_en", - "editable":false, - "validate":{ - - }, - "pk":false, - "default":"", - "input":{ - "type":"text", - "options":{ - - } - } - }, - { - "name":"countries_capital_en", - "type":"varchar", - "label":"countries_capital_en", - "editable":false, - "validate":{ - - }, - "pk":false, - "default":"", - "input":{ - "type":"text", - "options":{ - - } - } - }, - { - "name":"countries_name_de", - "type":"varchar", - "label":"countries_name_de", - "editable":false, - "validate":{ - - }, - "pk":false, - "default":"", - "input":{ - "type":"text", - "options":{ - - } - } - }, - { - "name":"countries_capital_de", - "type":"varchar", - "label":"countries_capital_de", - "editable":false, - "validate":{ - - }, - "pk":false, - "default":"", - "input":{ - "type":"text", - "options":{ - - } - } - }, - { - "name":"countries_name_it", - "type":"varchar", - "label":"countries_name_it", - "editable":false, - "validate":{ - - }, - "pk":false, - "default":"", - "input":{ - "type":"text", - "options":{ - - } - } - }, - { - "name":"countries_capital_it", - "type":"varchar", - "label":"countries_capital_it", - "editable":false, - "validate":{ - - }, - "pk":false, - "default":"", - "input":{ - "type":"text", - "options":{ - - } - } - }, - { - "name":"countries_name_fr", - "type":"varchar", - "label":"countries_name_fr", - "editable":false, - "validate":{ - - }, - "pk":false, - "default":"", - "input":{ - "type":"text", - "options":{ - - } - } - }, - { - "name":"countries_capital_fr", - "type":"varchar", - "label":"countries_capital_fr", - "editable":false, - "validate":{ - - }, - "pk":false, - "default":"", - "input":{ - "type":"text", - "options":{ - - } - } - }, - { - "name":"countries_name_br", - "type":"varchar", - "label":"countries_name_br", - "editable":false, - "validate":{ - - }, - "pk":false, - "default":"", - "input":{ - "type":"text", - "options":{ - - } - } - }, - { - "name":"countries_capital_br", - "type":"varchar", - "label":"countries_capital_br", - "editable":false, - "validate":{ - - }, - "pk":false, - "default":"", - "input":{ - "type":"text", - "options":{ - - } - } - }, - { - "name":"countries_name_es", - "type":"varchar", - "label":"countries_name_es", - "editable":false, - "validate":{ - - }, - "pk":false, - "default":"", - "input":{ - "type":"text", - "options":{ - - } - } - }, - { - "name":"countries_capital_es", - "type":"varchar", - "label":"countries_capital_es", - "editable":false, - "validate":{ - - }, - "pk":false, - "default":"", - "input":{ - "type":"text", - "options":{ - - } - } - }, - { - "name":"countries_population", - "type":"bigint", - "label":"countries_population", - "editable":false, - "validate":{ - - }, - "pk":false, - "default":"", - "input":{ - "type":"text", - "options":{ - - } - } - }, - { - "name":"countries_area_km2", - "type":"bigint", - "label":"countries_area_km2", - "editable":false, - "validate":{ - - }, - "pk":false, - "default":"", - "input":{ - "type":"text", - "options":{ - - } - } - }, - { - "name":"countries_iso_num", - "type":"bigint", - "label":"countries_iso_num", - "editable":false, - "validate":{ - - }, - "pk":false, - "default":"", - "input":{ - "type":"text", - "options":{ - - } - } - } - ] - }, - "featurelocks":null, - "constraints":{ - - }, - "capabilities": [ - "add_feature", - "change_feature", - "delete_feature", - "change_attr_feature" - ] + "result": true, + "vector": { + "format": "GeoJSON", + "count": null, + "data": null, + "geometrytype": "Point", + "fields": [{ + "name": "ogc_fid", + "type": "bigint", + "label": "ogc_fid", + "editable": false, + "validate": { + "required": true, + "unique": true + }, + "pk": true, + "default": "Autogenerate", + "input": { + "type": "text", + "options": {} + } + }, { + "name": "geonameid", + "type": "bigint", + "label": "geonameid", + "editable": true, + "validate": {}, + "pk": false, + "default": "", + "input": { + "type": "text", + "options": {} + } + }, { + "name": "name", + "type": "varchar", + "label": "name", + "editable": true, + "validate": {}, + "pk": false, + "default": "", + "input": { + "type": "text", + "options": {} + } + }, { + "name": "asciiname", + "type": "varchar", + "label": "asciiname", + "editable": true, + "validate": {}, + "pk": false, + "default": "", + "input": { + "type": "text", + "options": {} + } + }, { + "name": "iso2_code", + "type": "varchar", + "label": "iso2_code", + "editable": true, + "validate": {}, + "pk": false, + "default": "", + "input": { + "type": "text", + "options": {} + } + }, { + "name": "population", + "type": "bigint", + "label": "population", + "editable": true, + "validate": {}, + "pk": false, + "default": "", + "input": { + "type": "text", + "options": {} + } + }, { + "name": "gtopo30", + "type": "bigint", + "label": "gtopo30", + "editable": true, + "validate": {}, + "pk": false, + "default": "", + "input": { + "type": "text", + "options": {} + } + }, { + "name": "countries_ogc_fid", + "type": "bigint", + "label": "countries_ogc_fid", + "editable": false, + "validate": { + "required": true, + "unique": true + }, + "pk": false, + "default": "", + "input": { + "type": "text", + "options": {} + }, + "vectorjoin_id": "cities_54d40b01_2af8_4b17_8495_c5833485536e_vectorjoin_0" + }, { + "name": "countries_name_local", + "type": "varchar", + "label": "countries_name_local", + "editable": false, + "validate": {}, + "pk": false, + "default": "", + "input": { + "type": "text", + "options": {} + }, + "vectorjoin_id": "cities_54d40b01_2af8_4b17_8495_c5833485536e_vectorjoin_0" + }, { + "name": "countries_name_en", + "type": "varchar", + "label": "countries_name_en", + "editable": false, + "validate": {}, + "pk": false, + "default": "", + "input": { + "type": "text", + "options": {} + }, + "vectorjoin_id": "cities_54d40b01_2af8_4b17_8495_c5833485536e_vectorjoin_0" + }, { + "name": "countries_capital_en", + "type": "varchar", + "label": "countries_capital_en", + "editable": false, + "validate": {}, + "pk": false, + "default": "", + "input": { + "type": "text", + "options": {} + }, + "vectorjoin_id": "cities_54d40b01_2af8_4b17_8495_c5833485536e_vectorjoin_0" + }, { + "name": "countries_name_de", + "type": "varchar", + "label": "countries_name_de", + "editable": false, + "validate": {}, + "pk": false, + "default": "", + "input": { + "type": "text", + "options": {} + }, + "vectorjoin_id": "cities_54d40b01_2af8_4b17_8495_c5833485536e_vectorjoin_0" + }, { + "name": "countries_capital_de", + "type": "varchar", + "label": "countries_capital_de", + "editable": false, + "validate": {}, + "pk": false, + "default": "", + "input": { + "type": "text", + "options": {} + }, + "vectorjoin_id": "cities_54d40b01_2af8_4b17_8495_c5833485536e_vectorjoin_0" + }, { + "name": "countries_name_it", + "type": "varchar", + "label": "countries_name_it", + "editable": false, + "validate": {}, + "pk": false, + "default": "", + "input": { + "type": "text", + "options": {} + }, + "vectorjoin_id": "cities_54d40b01_2af8_4b17_8495_c5833485536e_vectorjoin_0" + }, { + "name": "countries_capital_it", + "type": "varchar", + "label": "countries_capital_it", + "editable": false, + "validate": {}, + "pk": false, + "default": "", + "input": { + "type": "text", + "options": {} + }, + "vectorjoin_id": "cities_54d40b01_2af8_4b17_8495_c5833485536e_vectorjoin_0" + }, { + "name": "countries_name_fr", + "type": "varchar", + "label": "countries_name_fr", + "editable": false, + "validate": {}, + "pk": false, + "default": "", + "input": { + "type": "text", + "options": {} + }, + "vectorjoin_id": "cities_54d40b01_2af8_4b17_8495_c5833485536e_vectorjoin_0" + }, { + "name": "countries_capital_fr", + "type": "varchar", + "label": "countries_capital_fr", + "editable": false, + "validate": {}, + "pk": false, + "default": "", + "input": { + "type": "text", + "options": {} + }, + "vectorjoin_id": "cities_54d40b01_2af8_4b17_8495_c5833485536e_vectorjoin_0" + }, { + "name": "countries_name_br", + "type": "varchar", + "label": "countries_name_br", + "editable": false, + "validate": {}, + "pk": false, + "default": "", + "input": { + "type": "text", + "options": {} + }, + "vectorjoin_id": "cities_54d40b01_2af8_4b17_8495_c5833485536e_vectorjoin_0" + }, { + "name": "countries_capital_br", + "type": "varchar", + "label": "countries_capital_br", + "editable": false, + "validate": {}, + "pk": false, + "default": "", + "input": { + "type": "text", + "options": {} + }, + "vectorjoin_id": "cities_54d40b01_2af8_4b17_8495_c5833485536e_vectorjoin_0" + }, { + "name": "countries_name_es", + "type": "varchar", + "label": "countries_name_es", + "editable": false, + "validate": {}, + "pk": false, + "default": "", + "input": { + "type": "text", + "options": {} + }, + "vectorjoin_id": "cities_54d40b01_2af8_4b17_8495_c5833485536e_vectorjoin_0" + }, { + "name": "countries_capital_es", + "type": "varchar", + "label": "countries_capital_es", + "editable": false, + "validate": {}, + "pk": false, + "default": "", + "input": { + "type": "text", + "options": {} + }, + "vectorjoin_id": "cities_54d40b01_2af8_4b17_8495_c5833485536e_vectorjoin_0" + }, { + "name": "countries_population", + "type": "bigint", + "label": "countries_population", + "editable": false, + "validate": {}, + "pk": false, + "default": "", + "input": { + "type": "text", + "options": {} + }, + "vectorjoin_id": "cities_54d40b01_2af8_4b17_8495_c5833485536e_vectorjoin_0" + }, { + "name": "countries_area_km2", + "type": "bigint", + "label": "countries_area_km2", + "editable": false, + "validate": {}, + "pk": false, + "default": "", + "input": { + "type": "text", + "options": {} + }, + "vectorjoin_id": "cities_54d40b01_2af8_4b17_8495_c5833485536e_vectorjoin_0" + }, { + "name": "countries_iso_num", + "type": "bigint", + "label": "countries_iso_num", + "editable": false, + "validate": {}, + "pk": false, + "default": "", + "input": { + "type": "text", + "options": {} + }, + "vectorjoin_id": "cities_54d40b01_2af8_4b17_8495_c5833485536e_vectorjoin_0" + }] + }, + "featurelocks": null, + "constraints": {}, + "capabilities": ["add_feature", "change_feature", "delete_feature", "change_attr_feature"] } \ No newline at end of file diff --git a/g3w-admin/editing/tests/data/logging_test.db b/g3w-admin/editing/tests/data/logging_test.db index b5c75561c..08ea2f2dd 100644 Binary files a/g3w-admin/editing/tests/data/logging_test.db and b/g3w-admin/editing/tests/data/logging_test.db differ diff --git a/g3w-admin/editing/tests/test_api.py b/g3w-admin/editing/tests/test_api.py index 0d708b1c1..fced001ef 100644 --- a/g3w-admin/editing/tests/test_api.py +++ b/g3w-admin/editing/tests/test_api.py @@ -176,6 +176,7 @@ def test_editing_api(self): # In more recent QGIS versions ogc_fid will have a required constraint try: + self.assertEqual(json.loads(response.content), res_expected) except AssertionError: actual = json.loads(response.content) diff --git a/g3w-admin/editing/views.py b/g3w-admin/editing/views.py index 16320269b..5f6f8314f 100644 --- a/g3w-admin/editing/views.py +++ b/g3w-admin/editing/views.py @@ -275,7 +275,7 @@ def form_valid(self, form): # give permission to viewers: toAdd = toRemove = None - if self.activated.pk: + if self.activated and self.activated.pk: currentViewerUsers = [int(i) for i in form.cleaned_data['viewer_users']] toRemove = list(set(self.initial_viewer_users) - set(currentViewerUsers)) toAdd = list(set(currentViewerUsers) - set(self.initial_viewer_users)) @@ -296,7 +296,7 @@ def form_valid(self, form): # give permission to user groups viewers: to_add = to_remove = None - if self.activated.pk: + if self.activated and self.activated.pk: current_user_groups_viewers = [int(i) for i in form.cleaned_data['user_groups_viewer']] to_remove = list(set(self.initial_viewer_user_groups) - set(current_user_groups_viewers)) to_add = list(set(current_user_groups_viewers) - set(self.initial_viewer_user_groups)) diff --git a/g3w-admin/filemanager/requirements.txt b/g3w-admin/filemanager/requirements.txt index 3d39d595e..940d6c7bf 100644 --- a/g3w-admin/filemanager/requirements.txt +++ b/g3w-admin/filemanager/requirements.txt @@ -1 +1 @@ -Werkzeug==2.2.3 \ No newline at end of file +Werkzeug==3.0.1 \ No newline at end of file diff --git a/g3w-admin/qdjango/api/utils/__init__.py b/g3w-admin/qdjango/api/utils/__init__.py index 19a650bcc..56a5274ac 100644 --- a/g3w-admin/qdjango/api/utils/__init__.py +++ b/g3w-admin/qdjango/api/utils/__init__.py @@ -15,12 +15,10 @@ def serialize_vectorjoin(layer_id, n, join): 'fieldRef': { 'referencedField': join['targetFieldName'], 'referencingField': join['joinFieldName'] - } + }, + 'editable': join['editable'], + 'prefix': join['prefix'] } - # if 'customPrefix' is set: - if 'customPrefix' in join: - ret['customPrefix'] = join['customPrefix'] - return ret diff --git a/g3w-admin/qdjango/models/constraints.py b/g3w-admin/qdjango/models/constraints.py index fc0cafa66..615dbb0e0 100644 --- a/g3w-admin/qdjango/models/constraints.py +++ b/g3w-admin/qdjango/models/constraints.py @@ -240,7 +240,7 @@ def get_constraints_for_anonymoususer(cls, layer_id, context='v'): if not constraints: return [] - return cls.objects.filter(anonymoususer=True) + return cls.objects.filter(anonymoususer=True, constraint__in=constraints) @classmethod def get_rule_definition_for_user(cls, user, layer_id, context='v'): diff --git a/g3w-admin/qdjango/tests/test_constraints.py b/g3w-admin/qdjango/tests/test_constraints.py index f215193ca..f610466ae 100644 --- a/g3w-admin/qdjango/tests/test_constraints.py +++ b/g3w-admin/qdjango/tests/test_constraints.py @@ -301,6 +301,16 @@ def test_anonymoususer_constraint(self): self.assertFalse(self._check_subset_string(login=False)) self.assertFalse(self._check_wfs_getfeature(login=False)) + # Contraints on more than one layer + constraint_anonymous = SingleLayerConstraint(layer=self.spatialite_points, active=True) + constraint_anonymous.save() + rule_anonymous = ConstraintSubsetStringRule( + constraint=constraint_anonymous, user=get_anonymous_user(), rule="pkuid = 1", anonymoususer=True) + rule_anonymous.save() + + self.assertFalse(self._check_subset_string(login=False)) + self.assertFalse(self._check_wfs_getfeature(login=False)) + def test_group_constraint(self): """Test model with group constraint""" diff --git a/g3w-admin/qdjango/utils/data.py b/g3w-admin/qdjango/utils/data.py index c678ed409..64c3e7ca0 100644 --- a/g3w-admin/qdjango/utils/data.py +++ b/g3w-admin/qdjango/utils/data.py @@ -190,6 +190,11 @@ def __init__(self, layer, **kwargs): if 'qgisProject' in kwargs: self.qgisProject = kwargs['qgisProject'] + # Get XML tree instance + self.qgisLayerTree = self.qgisProject.qgisProjectTree.\ + xpath(f"///maplayer/id[text()='{self.qgs_layer.id()}']")[0].\ + getparent() + # FIXME: check il order on layer is used self.order = kwargs['order'] if 'order' in kwargs else 0 @@ -375,22 +380,41 @@ def _getDataVectorjoins(self): :rtype: list, None """ + # Get xml layer tree element to get property not available by Python API: hasCustomPrefix + layer_tree_vectorjoins = self.qgisLayerTree.find('vectorjoins') + # get root of layer-tree-group ret = [] try: vectorjoins = self.qgs_layer.vectorJoins() + + + for order, join in enumerate(vectorjoins): + + # Prefix management + # If sert custom prefix and the value is '', continue for cycle to avoid relation save + if layer_tree_vectorjoins[order].get('hasCustomPrefix') == '1' and join.prefix() == '': + continue + else: + if layer_tree_vectorjoins[order].get("hasCustomPrefix") == "1": + prefix = join.prefix() + else: + prefix = f"{join.joinLayer().name()}_" + + ret.append( { "cascadedDelete": str(int(join.hasCascadedDelete())), "targetFieldName": join.targetFieldName(), - "editable": str(int(join.isEditable())), + "editable": join.isEditable(), "memoryCache": str(int(join.isUsingMemoryCache())), "upsertOnEdit": str(int(join.hasUpsertOnEdit())), "joinLayerId": join.joinLayerId(), "dynamicForm": str(int(join.isDynamicFormEnabled())), - "joinFieldName": join.joinFieldName() - + "joinFieldName": join.joinFieldName(), + "hasCustomPrefix": True if layer_tree_vectorjoins[order].get('hasCustomPrefix') == '1' else False, + "prefix": prefix } )