Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ Allow to store layer's expression filters (authenticathed users) #623

Merged
merged 27 commits into from
Oct 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion g3w-admin/client/static/client/css/app.min.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion g3w-admin/client/static/client/js/app.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion g3w-admin/editing/static/editing/js/plugin.js

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions g3w-admin/qdjango/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,16 @@ class SessionTokenFilterAdmin(admin.ModelAdmin):
]


@admin.register(FilterLayerSaved)
class FilterLayerSavedAdmin(admin.ModelAdmin):
list_display = (
'user',
'layer',
'qgs_expr',
'created',
'modified',
)

class QgisAuthAdminForm(ModelForm):

username = CharField()
Expand Down
22 changes: 21 additions & 1 deletion g3w-admin/qdjango/api/layers/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
__date__ = '2020-05-06'
__copyright__ = 'Copyright 2015 - 2020, Gis3w'

from qdjango.models import Layer
from qdjango.models import Layer, FilterLayerSaved
from rest_framework import serializers
from usersmanage.models import User, Group as AuthGroup

Expand All @@ -36,3 +36,23 @@ class Meta:
fields = ['pk', 'name']


class FilterLayerSavedSerializer(serializers.ModelSerializer):

class Meta:
model = FilterLayerSaved
fields = (
'id',
'name',
)

def to_representation(self, instance):

ret = super().to_representation(instance)

# Change pk(id) with fid
del(ret['id'])
ret['fid'] = instance.pk

return ret


39 changes: 37 additions & 2 deletions g3w-admin/qdjango/api/projects/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,21 @@
from rest_framework import serializers
from rest_framework.fields import empty
from owslib.wms import WebMapService
from qdjango.models import Project, Layer, Widget, SessionTokenFilter, GeoConstraintRule, MSG_LEVELS
from qdjango.models import (
Project,
Layer,
Widget,
SessionTokenFilter,
GeoConstraintRule,
MSG_LEVELS,
FilterLayerSaved
)
from qdjango.utils.data import QGIS_LAYER_TYPE_NO_GEOM
from qdjango.utils.models import get_capabilities4layer, get_view_layer_ids
from qdjango.signals import load_qdjango_widget_layer
from qdjango.apps import get_qgs_project
from qdjango.utils.structure import QdjangoMetaLayer, datasourcearcgis2dict
from qdjango.api.layers.serializers import FilterLayerSavedSerializer
from core.utils.structure import mapLayerAttributes
from core.configs import *
from core.signals import after_serialized_project_layer
Expand Down Expand Up @@ -412,6 +421,16 @@ def to_representation(self, instance):
meta_layer = QdjangoMetaLayer()
to_remove_from_layerstree = []

# Get FilterToken layer filters saved:
# Build a layer_filters dict to pass FilterLayerSaved instance to LayerSerializer
layer_filters = {}
filters = FilterLayerSaved.objects.filter(user=self.request.user, layer__project=instance)
for f in filters:
if f.layer.qgs_layer_id not in layer_filters:
layer_filters[f.layer.qgs_layer_id] = []
layer_filters[f.layer.qgs_layer_id].append(f)


def readLeaf(layer, container):

if 'nodes' in layer:
Expand All @@ -431,7 +450,12 @@ def readLeaf(layer, container):

try:
layer_serialized = LayerSerializer(
layers[layer['id']], qgs_project=qgs_project, request=self.request, layertreenode=layer)
layers[layer['id']],
qgs_project=qgs_project,
request=self.request,
layertreenode=layer,
filters=layer_filters[layer['id']] if layer['id'] in layer_filters else []
)
except KeyError:
logger.error(
'Layer %s is missing from QGIS project!' % layer['id'])
Expand Down Expand Up @@ -600,6 +624,10 @@ def __init__(self, instance=None, data=empty, **kwargs):
self.layertreenode = kwargs['layertreenode']
del (kwargs['layertreenode'])

# FilterLayerSaved
self.filters = kwargs['filters']
del (kwargs['filters'])

super(LayerSerializer, self).__init__(instance, data, **kwargs)

class Meta:
Expand Down Expand Up @@ -849,6 +877,13 @@ def to_representation(self, instance):
if 'showfeaturecount' in self.layertreenode and self.layertreenode['showfeaturecount']:
ret['featurecount'] = get_qgis_featurecount(qgs_maplayer)


# Set FilterLayerSaved instances
if len(self.filters) > 0:
ret['filters'] = []
for f in self.filters:
ret['filters'].append(FilterLayerSavedSerializer(f).data)

return ret


Expand Down
29 changes: 29 additions & 0 deletions g3w-admin/qdjango/migrations/0109_filterlayersaved.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Generated by Django 3.2.20 on 2023-10-13 15:07

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
import model_utils.fields


class Migration(migrations.Migration):

dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('qdjango', '0108_alter_layer_slug'),
]

operations = [
migrations.CreateModel(
name='FilterLayerSaved',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, editable=False, verbose_name='created')),
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, editable=False, verbose_name='modified')),
('qgs_expr', models.TextField()),
('layer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='qdjango.layer')),
('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, to=settings.AUTH_USER_MODEL)),
],
),
]
18 changes: 18 additions & 0 deletions g3w-admin/qdjango/migrations/0110_sessiontokenfilterlayer_name.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 3.2.20 on 2023-10-16 12:47

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('qdjango', '0109_filterlayersaved'),
]

operations = [
migrations.AddField(
model_name='sessiontokenfilterlayer',
name='name',
field=models.TextField(null=True),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 3.2.20 on 2023-10-16 13:06

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('qdjango', '0110_sessiontokenfilterlayer_name'),
]

operations = [
migrations.AlterField(
model_name='sessiontokenfilterlayer',
name='name',
field=models.TextField(null=True, unique=True),
),
]
22 changes: 22 additions & 0 deletions g3w-admin/qdjango/migrations/0112_auto_20231017_0752.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Generated by Django 3.2.20 on 2023-10-17 07:52

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('qdjango', '0111_alter_sessiontokenfilterlayer_name'),
]

operations = [
migrations.RemoveField(
model_name='sessiontokenfilterlayer',
name='name',
),
migrations.AddField(
model_name='filterlayersaved',
name='name',
field=models.TextField(null=True, unique=True),
),
]
24 changes: 24 additions & 0 deletions g3w-admin/qdjango/migrations/0113_auto_20231019_1237.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Generated by Django 3.2.20 on 2023-10-19 12:37

from django.conf import settings
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('qdjango', '0112_auto_20231017_0752'),
]

operations = [
migrations.AlterField(
model_name='filterlayersaved',
name='name',
field=models.TextField(null=True),
),
migrations.AlterUniqueTogether(
name='filterlayersaved',
unique_together={('user', 'layer', 'name')},
),
]
20 changes: 19 additions & 1 deletion g3w-admin/qdjango/models/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from django.db import models
from django.utils.http import int_to_base36
from django.utils.crypto import salted_hmac
from model_utils.models import TimeStampedModel
from usersmanage.models import User
from .projects import Layer
from datetime import datetime
Expand Down Expand Up @@ -86,12 +87,29 @@ class Meta:

class SessionTokenFilterLayer(models.Model):
"""
Model to save qgis espresion for layer by session token filter.
Model to save qgis expression for layer by session token filter.
"""

session_token_filter = models.ForeignKey(SessionTokenFilter, on_delete=models.CASCADE, related_name='stf_layers')
layer = models.ForeignKey(Layer, on_delete=models.CASCADE)
qgs_expr = models.TextField()


class Meta:
app_label = 'qdjango'


class FilterLayerSaved(TimeStampedModel):
"""
Model to save qgis expression for layer by user.
"""

user = models.ForeignKey(User, null=True, blank=True, on_delete=models.DO_NOTHING)
layer = models.ForeignKey(Layer, on_delete=models.CASCADE)
qgs_expr = models.TextField()
name = models.TextField(null=True)

class Meta:
app_label = 'qdjango'
unique_together = ['user', 'layer', 'name']

Binary file modified g3w-admin/qdjango/tests/data/geodata/qgis_widget_test_data.gpkg
Binary file not shown.
Loading
Loading