Skip to content

Commit 3e741bc

Browse files
committed
added usergroup model and migrations
1 parent faa3212 commit 3e741bc

File tree

7 files changed

+199
-29
lines changed

7 files changed

+199
-29
lines changed

django/gsmap/admin.py

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from parler.admin import TranslatableAdmin
1111
from parler.forms import TranslatableModelForm
1212
from sortedm2m_filter_horizontal_widget.forms import SortedFilteredSelectMultiple
13-
from gsmap.models import Municipality, Snapshot, Workspace, Category, Attachement, Annotation
13+
from gsmap.models import Municipality, Snapshot, Workspace, Category, Usergroup, Attachement, Annotation
1414

1515

1616
class MunicipalityAdmin(admin.OSMGeoAdmin):
@@ -134,15 +134,15 @@ class WorkspaceAdmin(admin.OSMGeoAdmin):
134134
('mode'),
135135
('findme_enabled', 'annotations_open', 'annotations_likes_enabled', 'polygon_open', 'polygon_likes_enabled'),
136136
('annotations_contact_name', 'annotations_contact_email'),
137-
'categories',
137+
'categories', 'usergroups'
138138
)
139139
}),
140140
)
141141
list_display = ('id', 'title', 'annotations_open', 'created', 'modified')
142142
search_fields = ['title']
143143

144144
def formfield_for_manytomany(self, db_field, request=None, **kwargs):
145-
if db_field.name == 'snapshots' or db_field.name == 'categories':
145+
if db_field.name == 'snapshots' or db_field.name == 'categories' or db_field.name == 'usergroups':
146146
kwargs['widget'] = SortedFilteredSelectMultiple()
147147
return super().formfield_for_manytomany(db_field, request, **kwargs)
148148

@@ -159,7 +159,7 @@ class AnnotationAdmin(admin.OSMGeoAdmin):
159159
)
160160
}),
161161
(_('Main'), {
162-
'fields': ('kind', 'data', 'category', 'rating', 'workspace','deleted', 'public'),
162+
'fields': ('kind', 'data', 'category', 'usergroup', 'rating', 'workspace','deleted', 'public'),
163163
}),
164164
)
165165
list_display = (
@@ -175,7 +175,7 @@ class AnnotationAdmin(admin.OSMGeoAdmin):
175175
'workspace',
176176
)
177177
inlines = [ AttachementInline, ]
178-
list_filter = ('workspace', 'category', 'kind')
178+
list_filter = ('workspace', 'category', 'kind', 'usergroup')
179179
search_fields = ('id', 'data')
180180

181181
class CategoryAdminForm(TranslatableModelForm):
@@ -214,13 +214,27 @@ class CategoryAdmin(TranslatableAdmin): # admin.OSMGeoAdmin,
214214
list_filter = ('namespace', 'hide_in_list', 'color')
215215
search_fields = ('id', 'translations__name', 'namespace')
216216

217-
# def get_prepopulated_fields(self, request, obj=None):
218-
# return {
219-
# 'slug': ('name',)
220-
# }
217+
class UsergroupAdmin(TranslatableAdmin): # admin.OSMGeoAdmin,
218+
readonly_fields = ('created', 'modified')
219+
fieldsets = (
220+
(_('Meta'), {
221+
'fields': ('deleted', 'created', 'modified'),
222+
}),
223+
(_('Category'), {
224+
'fields': ('key', 'name'),
225+
}),
226+
)
227+
228+
list_display = (
229+
'key',
230+
'name',
231+
)
232+
233+
search_fields = ('id', 'name', 'key')
221234

222235
admin.site.register(Municipality, MunicipalityAdmin)
223236
admin.site.register(Snapshot, SnapshotAdmin)
224237
admin.site.register(Workspace, WorkspaceAdmin)
225238
admin.site.register(Category, CategoryAdmin)
239+
admin.site.register(Usergroup, UsergroupAdmin)
226240
admin.site.register(Annotation, AnnotationAdmin)
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# Generated by Django 3.1.13 on 2022-02-23 10:48
2+
3+
from django.db import migrations, models
4+
import django.db.models.deletion
5+
from django.utils.text import slugify
6+
import parler.fields
7+
import parler.models
8+
import sortedm2m.fields
9+
10+
def forwards_func(apps, schema_editor):
11+
Annotation = apps.get_model('gsmap', 'Annotation')
12+
Usergroup = apps.get_model('gsmap', 'Usergroup')
13+
14+
usergroups = list(map(get_usergroup_from_data, Annotation.objects.all()))
15+
usergroups = [x for i, x in enumerate(usergroups) if usergroups.index(x) == i and x is not None]
16+
17+
for usergroup in usergroups:
18+
exists = list(Usergroup.objects.filter(key=create_usergroup_key(usergroup)))
19+
if len(exists) == 0:
20+
g = Usergroup(
21+
key=create_usergroup_key(usergroup)
22+
)
23+
g.set_current_language("de")
24+
g.name = usergroup
25+
g.save()
26+
27+
for object in Annotation.objects.all():
28+
usergroup = get_usergroup_from_data(object)
29+
if usergroup:
30+
object.usergroup = Usergroup.objects.filter(key=create_usergroup_key(usergroup)).first()
31+
object.data["properties"].pop("usergroup")
32+
object.save()
33+
34+
def backwards_func(apps, schema_editor):
35+
Annotation = apps.get_model('gsmap', 'Annotation')
36+
37+
for object in Annotation.objects.all():
38+
if object.usergroup:
39+
object.data["properties"]["usergroup"] = object.usergroup.get_translation("de").name
40+
object.save() # Note this only calls Model.save()
41+
42+
def get_usergroup_from_data(annotation):
43+
data = annotation.data
44+
if "properties" in data.keys() and "usergroup" in data["properties"].keys():
45+
return data["properties"]["usergroup"]
46+
return None
47+
48+
def create_usergroup_key(usergroup):
49+
return slugify(usergroup)[:50]
50+
51+
class Migration(migrations.Migration):
52+
53+
dependencies = [
54+
('gsmap', '0035_auto_20220222_2317'),
55+
]
56+
57+
operations = [
58+
migrations.CreateModel(
59+
name='Usergroup',
60+
fields=[
61+
('created', models.DateTimeField(auto_now_add=True)),
62+
('modified', models.DateTimeField(auto_now=True)),
63+
('deleted', models.BooleanField(default=False)),
64+
('key', models.CharField(max_length=50, primary_key=True, serialize=False, unique=True)),
65+
],
66+
options={
67+
'verbose_name_plural': 'usergroups',
68+
},
69+
bases=(parler.models.TranslatableModelMixin, models.Model),
70+
),
71+
migrations.AddField(
72+
model_name='annotation',
73+
name='usergroup',
74+
field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, to='gsmap.usergroup'),
75+
),
76+
migrations.AddField(
77+
model_name='workspace',
78+
name='usergroups',
79+
field=sortedm2m.fields.SortedManyToManyField(help_text=None, to='gsmap.Usergroup'),
80+
),
81+
migrations.CreateModel(
82+
name='UsergroupTranslation',
83+
fields=[
84+
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
85+
('language_code', models.CharField(db_index=True, max_length=15, verbose_name='Language')),
86+
('name', models.CharField(max_length=255)),
87+
('master', parler.fields.TranslationsForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='translations', to='gsmap.usergroup')),
88+
],
89+
options={
90+
'verbose_name': 'usergroup Translation',
91+
'db_table': 'gsmap_usergroup_translation',
92+
'db_tablespace': '',
93+
'managed': True,
94+
'default_permissions': (),
95+
'unique_together': {('language_code', 'master')},
96+
},
97+
bases=(parler.models.TranslatedFieldsModelMixin, models.Model),
98+
),
99+
100+
# Also migrate data from/to inside data json field
101+
migrations.RunPython(forwards_func, backwards_func),
102+
]

django/gsmap/models.py

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,27 @@ class Meta:
344344
def __str__(self):
345345
return f'{self.namespace}/{self.name}'
346346

347+
class Usergroup(TranslatableModel):
348+
class Meta:
349+
verbose_name_plural = 'usergroups'
350+
# ordering = ['name']
351+
352+
created = models.DateTimeField(auto_now_add=True)
353+
modified = models.DateTimeField(auto_now=True)
354+
deleted = models.BooleanField(default=False)
355+
356+
key = models.CharField(
357+
max_length=50, unique=True,
358+
primary_key=True
359+
)
360+
361+
translations = TranslatedFields(
362+
name=models.CharField(max_length=255),
363+
)
364+
365+
def __str__(self):
366+
return f'{self.name}'
367+
347368
class Workspace(models.Model):
348369
class Meta:
349370
ordering = ['-created']
@@ -361,6 +382,7 @@ class Meta:
361382
snapshots = SortedManyToManyField(Snapshot)
362383

363384
categories = SortedManyToManyField(Category)
385+
usergroups = SortedManyToManyField(Usergroup)
364386

365387
MODE_CHOICES = [
366388
("OFF", _("Off")),
@@ -429,6 +451,10 @@ class Meta:
429451
Category, default=None, blank=True,
430452
null=True, on_delete=models.SET_NULL
431453
)
454+
usergroup = models.ForeignKey(
455+
Usergroup, default=None, blank=True,
456+
null=True, on_delete=models.SET_NULL
457+
)
432458
author_email = models.EmailField(max_length=254)
433459
rating = models.DecimalField(default=0, decimal_places=2, max_digits=6)
434460
workspace = models.ForeignKey(Workspace, on_delete=models.CASCADE)
@@ -460,13 +486,6 @@ def description(self):
460486
else:
461487
return None
462488

463-
@property
464-
def usergroup(self):
465-
if "properties" in self.data.keys() and "usergroup" in self.data["properties"].keys():
466-
return f'{self.data["properties"]["usergroup"]}'
467-
else:
468-
return None
469-
470489
def __str__(self):
471490
return self.fullname
472491

django/gsmap/schema.py

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from graphene_django.types import DjangoObjectType
1212
from graphene_django.filter import DjangoFilterConnectionField
1313
from graphene_django.converter import convert_django_field
14-
from gsmap.models import Municipality, Snapshot, SnapshotPermission, Workspace, Annotation, Category, Attachement
14+
from gsmap.models import Municipality, Snapshot, SnapshotPermission, Workspace, Annotation, Category, Usergroup, Attachement
1515
from graphene_django.rest_framework.mutation import SerializerMutation
1616
import graphene_django_optimizer as gql_optimizer
1717

@@ -122,12 +122,32 @@ class Meta:
122122
interfaces = [graphene.relay.Node]
123123

124124
name = graphene.String(
125-
language_code=graphene.Argument(Q_LANGUAGE, default_value=translation.get_language()),
125+
language_code=graphene.Argument(Q_LANGUAGE, default_value=Q_LANGUAGE[settings.PARLER_DEFAULT_LANGUAGE_CODE]),
126126
)
127127
pk = graphene.Int(source='id')
128128

129-
def resolve_name(root: Category, info, language_code=None):
130-
return root.safe_translation_getter("name", language_code=language_code)
129+
def resolve_name(self, info, language_code=None):
130+
lang = Q_LANGUAGE.get(language_code).name
131+
return self.safe_translation_getter("name", language_code=lang)
132+
133+
class UsergroupNode(DjangoObjectType):
134+
class Meta:
135+
model = Usergroup
136+
fields = ['key', 'name']
137+
filter_fields = {
138+
'key': ['exact'],
139+
'name': ['exact', 'icontains', 'istartswith'],
140+
}
141+
interfaces = [graphene.relay.Node]
142+
143+
name = graphene.String(
144+
language_code=graphene.Argument(Q_LANGUAGE, default_value=Q_LANGUAGE[settings.PARLER_DEFAULT_LANGUAGE_CODE]),
145+
)
146+
key = graphene.String(source='key')
147+
148+
def resolve_name(self, info, language_code=None):
149+
lang = Q_LANGUAGE.get(language_code).name
150+
return self.safe_translation_getter("name", language_code=lang)
131151

132152
class AttachementNode(DjangoObjectType):
133153
class Meta:
@@ -170,6 +190,8 @@ class Meta:
170190
CategoryNode,
171191
show_all=graphene.Argument(graphene.Boolean, default_value=False),
172192
)
193+
194+
usergroups = graphene.List(UsergroupNode)
173195

174196
def resolve_snapshots(self, info):
175197
return gql_optimizer.query(self.snapshots.all(), info)
@@ -182,6 +204,9 @@ def resolve_categories(self, info, show_all):
182204
return gql_optimizer.query(self.categories.all(),info)
183205
else:
184206
return gql_optimizer.query(self.categories.filter(Q(hide_in_list=0)),info)
207+
208+
def resolve_usergroups(self, info):
209+
return gql_optimizer.query(self.usergroups.all(), info)
185210

186211
class SnapshotMutation(graphene.relay.ClientIDMutation):
187212
class Input:

django/gsmap/serializers.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,17 @@ class Meta:
1717
'data',
1818
'category',
1919
'author_email',
20+
'usergroup',
2021
'workspace',
2122
)
2223

2324
def validate(self, data):
24-
if not data.get("workspace").annotations_open:
25-
raise serializers.ValidationError(f'Rating annotations is not allowed currently for this workspace.')
25+
if not (data.get("workspace").annotations_open or data.get("workspace").poylgons_open):
26+
raise serializers.ValidationError('Rating annotations is not allowed currently for this workspace.')
2627
if not data.get("author_email"):
27-
raise serializers.ValidationError(f'Adding annotations to this workspace requires an email.')
28+
raise serializers.ValidationError('Adding annotations to this workspace requires an email.')
29+
if not data.get("usergroup"):
30+
raise serializers.ValidationError('Adding annotations to this workspace requires a usergroup.')
2831

2932
return data
3033

vue/src/components/SnapshotMap.vue

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,9 @@
231231
required
232232
/>
233233
<v-select
234-
:items="usergroups"
234+
:items="annotations.usergroups"
235+
item-text="name"
236+
item-value="key"
235237
v-model="newAnnotation.usergroup"
236238
label="Personengruppe"
237239
:rules="[v => !!v || $t('mandatory')]"
@@ -612,7 +614,6 @@ export default {
612614
timeout: null,
613615
guides: null,
614616
commentstepper: 1,
615-
usergroups: ['Anwohner:in', 'Bürger:in', 'Beschäftigte:r', 'Student:in', 'Andere'],
616617
currentCommentIndex: null,
617618
ratingpause: false,
618619
dialog: false,
@@ -1247,12 +1248,12 @@ export default {
12471248
properties: {
12481249
fill: true,
12491250
title: this.newAnnotation.title,
1250-
description: this.newAnnotation.text,
1251-
usergroup: this.newAnnotation.usergroup
1251+
description: this.newAnnotation.text
12521252
}
12531253
};
12541254
formData.append('category', this.newAnnotation.category);
12551255
formData.append('author_email', this.newAnnotation.email);
1256+
formData.append('usergroup', this.newAnnotation.usergroup);
12561257
formData.append('data', JSON.stringify(data));
12571258
break;
12581259
}
@@ -1269,12 +1270,12 @@ export default {
12691270
},
12701271
properties: {
12711272
title: this.newAnnotation.title,
1272-
description: this.newAnnotation.text,
1273-
usergroup: this.newAnnotation.usergroup
1273+
description: this.newAnnotation.text
12741274
}
12751275
};
12761276
formData.append('category', this.newAnnotation.category);
12771277
formData.append('author_email', this.newAnnotation.email);
1278+
formData.append('usergroup', this.newAnnotation.usergroup);
12781279
formData.append('data', JSON.stringify(data));
12791280
break;
12801281
}

0 commit comments

Comments
 (0)