From 1794c89b0c021aa123663b30062335da890bd6df Mon Sep 17 00:00:00 2001 From: Mattia Giupponi Date: Thu, 4 Feb 2021 12:34:30 +0100 Subject: [PATCH] Resolves #6925: fix metadata bug that prevent to save multiple key for each thesaurus --- geonode/base/fields.py | 9 ++++++ geonode/base/forms.py | 13 +++++---- geonode/layers/views.py | 65 +++++++++++++++++++++++------------------ 3 files changed, 54 insertions(+), 33 deletions(-) diff --git a/geonode/base/fields.py b/geonode/base/fields.py index 825f914bbcc..2412d9f0318 100644 --- a/geonode/base/fields.py +++ b/geonode/base/fields.py @@ -28,3 +28,12 @@ def label_from_instance(self, obj): # code. The hard-coded language is currently used throughout # geonode. return obj.keyword.filter(lang='en').first().label + + +class MultiThesauriXField(forms.MultipleChoiceField): + + def label_from_instance(self, obj): + # Note: Not using .get() because filter()[0] is used in original + # code. The hard-coded language is currently used throughout + # geonode. + return obj.keyword.filter(lang='en').first().label diff --git a/geonode/base/forms.py b/geonode/base/forms.py index 08393c14646..2e83a94e52a 100644 --- a/geonode/base/forms.py +++ b/geonode/base/forms.py @@ -20,6 +20,7 @@ import html import logging import re +from django.db.models.query import QuerySet import six from bootstrap3_datetime.widgets import DateTimePicker @@ -333,12 +334,14 @@ def __init__(self, *args, **kwargs): elif item.card_max == -1 and item.card_min==1: self.fields[f'{item.id}'] = self._define_multifield(item, True, tname, lang) - def clean(self): - cleaned_data = self.data + def cleanx(self, x): cleaned_values = [] - for key, value in cleaned_data.items(): - if key.startswith('tkeywords') and len(value) > 0: - cleaned_values.append(value) + for key, value in x.items(): + if isinstance(value, QuerySet): + for y in value: + cleaned_values.append(y.id) + elif value: + cleaned_values.append(value.id) return ThesaurusKeyword.objects.filter(id__in=cleaned_values) @staticmethod diff --git a/geonode/layers/views.py b/geonode/layers/views.py index 71915d4b0cc..9137a484506 100644 --- a/geonode/layers/views.py +++ b/geonode/layers/views.py @@ -900,6 +900,7 @@ def layer_metadata( current_keywords = [keyword.name for keyword in layer.keywords.all()] topic_category = layer.category + topic_thesaurus = layer.tkeywords.all() # Add metadata_author or poc if missing layer.add_missing_metadata_author_or_poc() @@ -1043,41 +1044,49 @@ def layer_metadata( prefix="category_choice_field", initial=topic_category.id if topic_category else None) - # Create THESAURUS widgets lang = settings.THESAURUS_DEFAULT_LANG if hasattr(settings, 'THESAURUS_DEFAULT_LANG') else 'en' if hasattr(settings, 'THESAURUS') and settings.THESAURUS: warnings.warn('The settings for Thesaurus has been moved to Model, this feature will be removed in next releases', DeprecationWarning) tkeywords_form = TKeywordForm(instance=layer) else: - tkeywords_form = ThesaurusAvailableForm(prefix='tkeywords') - # Keywords from THESAURUS management - #layer_tkeywords = layer.tkeywords.all() - #tkeywords_list = '' - #lang = 'en' # TODO: use user's language - #if layer_tkeywords and len(layer_tkeywords) > 0: - # tkeywords_ids = layer_tkeywords.values_list('id', flat=True) - # if hasattr(settings, 'THESAURUS') and settings.THESAURUS: - # el = settings.THESAURUS - # thesaurus_name = el['name'] - # try: - # t = Thesaurus.objects.get(identifier=thesaurus_name) - # for tk in t.thesaurus.filter(pk__in=tkeywords_ids): - # tkl = tk.keyword.filter(lang=lang) - # if len(tkl) > 0: - # tkl_ids = ",".join( - # map(str, tkl.values_list('id', flat=True))) - # tkeywords_list += "," + \ - # tkl_ids if len( - # tkeywords_list) > 0 else tkl_ids - # except Exception: - # tb = traceback.format_exc() - # logger.error(tb) - #tkeywords_form = TKeywordForm(instance=layer) + layer_tkeywords = layer.tkeywords.all() + tkeywords_list = '' + lang = 'en' # TODO: use user's language + if layer_tkeywords and len(layer_tkeywords) > 0: + tkeywords_ids = layer_tkeywords.values_list('id', flat=True) + if hasattr(settings, 'THESAURUS') and settings.THESAURUS: + el = settings.THESAURUS + thesaurus_name = el['name'] + try: + t = Thesaurus.objects.get(identifier=thesaurus_name) + for tk in t.thesaurus.filter(pk__in=tkeywords_ids): + tkl = tk.keyword.filter(lang=lang) + if len(tkl) > 0: + tkl_ids = ",".join( + map(str, tkl.values_list('id', flat=True))) + tkeywords_list += "," + \ + tkl_ids if len( + tkeywords_list) > 0 else tkl_ids + except Exception: + tb = traceback.format_exc() + logger.error(tb) + #tkeywords_form = TKeywordForm(instance=layer) + tkeywords_form = ThesaurusAvailableForm( + prefix='tkeywords', + ) + # set initial values for thesaurus form + for x in tkeywords_form.fields: + values = [] + for y in topic_thesaurus: + if int(x) == y.thesaurus.id: + values.append(y.id) + tkeywords_form.fields[x].initial = values + if request.method == "POST" and layer_form.is_valid() and attribute_form.is_valid( - ) and category_form.is_valid(): + ) and category_form.is_valid() and tkeywords_form.is_valid(): new_poc = layer_form.cleaned_data['poc'] new_author = layer_form.cleaned_data['metadata_author'] @@ -1176,8 +1185,8 @@ def layer_metadata( ) layer.tkeywords.set(tkeywords_data) elif Thesaurus.objects.all().exists(): - tkeywords_data = tkeywords_form.clean() - layer.tkeywords.set(tkeywords_data) + x = tkeywords_form.cleaned_data + layer.tkeywords.set(tkeywords_form.cleanx(x)) except Exception: tb = traceback.format_exc()