From 6ace0ed010d0d6cbaa8f30a76013b660be494133 Mon Sep 17 00:00:00 2001 From: Dimas Ciputra Date: Wed, 24 Jul 2024 12:58:48 +0100 Subject: [PATCH] Fix the taxa upload bug with multiple IUCN statuses (#4101) --- bims/apps.py | 41 ++++++++++++++++++---------------- bims/scripts/taxa_upload.py | 26 ++++++++++++++++----- bims/tests/test_taxa_upload.py | 22 ++++++++++++++---- 3 files changed, 61 insertions(+), 28 deletions(-) diff --git a/bims/apps.py b/bims/apps.py index 185297ac3..36a6df774 100644 --- a/bims/apps.py +++ b/bims/apps.py @@ -6,23 +6,26 @@ class BimsAppConfig(AppConfig): name = 'bims' def ready(self): - from easyaudit.signals.model_signals import m2m_changed - is_ready = True - def easy_audit_m2m_changed(sender, instance, action, reverse, model, pk_set, using, **kwargs): - if not pk_set: - return - if len(list(pk_set)) == 0: - return - return m2m_changed( - sender, - instance, - action, - reverse, - model, - pk_set, - using, - **kwargs - ) + try: + from easyaudit.signals.model_signals import m2m_changed + is_ready = True + def easy_audit_m2m_changed(sender, instance, action, reverse, model, pk_set, using, **kwargs): + if not pk_set: + return + if len(list(pk_set)) == 0: + return + return m2m_changed( + sender, + instance, + action, + reverse, + model, + pk_set, + using, + **kwargs + ) - signals.m2m_changed.disconnect(dispatch_uid='easy_audit_signals_m2m_changed') - signals.m2m_changed.connect(easy_audit_m2m_changed, dispatch_uid='easy_audit_signals_m2m_changed') + signals.m2m_changed.disconnect(dispatch_uid='easy_audit_signals_m2m_changed') + signals.m2m_changed.connect(easy_audit_m2m_changed, dispatch_uid='easy_audit_signals_m2m_changed') + except RuntimeError: + pass diff --git a/bims/scripts/taxa_upload.py b/bims/scripts/taxa_upload.py index 5e02d4054..8b2743b5a 100644 --- a/bims/scripts/taxa_upload.py +++ b/bims/scripts/taxa_upload.py @@ -62,8 +62,10 @@ def endemism(self, row): def conservation_status(self, row, global_cons = False): """Processing conservation status""" + national = False if global_cons: - cons_status = DataCSVUpload.row_value(row, CONSERVATION_STATUS) + cons_status = DataCSVUpload.row_value( + row, CONSERVATION_STATUS) if not cons_status: cons_status = DataCSVUpload.row_value( row, CONSERVATION_STATUS_GLOBAL) @@ -72,10 +74,18 @@ def conservation_status(self, row, global_cons = False): else: cons_status = DataCSVUpload.row_value( row, CONSERVATION_STATUS_NATIONAL) + national = True if cons_status: - iucn_status, _ = IUCNStatus.objects.get_or_create( - category=IUCN_CATEGORIES[cons_status.lower()] - ) + try: + iucn_status, _ = IUCNStatus.objects.get_or_create( + category=IUCN_CATEGORIES[cons_status.lower()], + national=national + ) + except IUCNStatus.MultipleObjectsReturned: + iucn_status = IUCNStatus.objects.filter( + category=IUCN_CATEGORIES[cons_status.lower()], + national=national + ).first() return iucn_status else: return None @@ -313,6 +323,7 @@ def synonym_key(self, field_key): def process_data(self, row, taxon_group: TaxonGroup): """Processing row of the csv files""" + taxonomic_status = DataCSVUpload.row_value(row, TAXONOMIC_STATUS) taxon_name = DataCSVUpload.row_value(row, TAXON) accepted_taxon = None @@ -462,8 +473,13 @@ def process_data(self, row, taxon_group: TaxonGroup): # Data from GBIF couldn't be found, so add it manually if not taxonomy: + max_try = 10 + current_try = 0 parent_name = parent_rank(rank) - while not DataCSVUpload.row_value(row, parent_name) and parent_name != KINGDOM: + while ( + not DataCSVUpload.row_value(row, parent_name) and parent_name != KINGDOM and current_try < max_try + ): + current_try += 1 parent_name = parent_rank(parent_name) parent = self.get_parent(row, parent_name) diff --git a/bims/tests/test_taxa_upload.py b/bims/tests/test_taxa_upload.py index c0fd4d69d..43a8bb2a8 100644 --- a/bims/tests/test_taxa_upload.py +++ b/bims/tests/test_taxa_upload.py @@ -13,7 +13,8 @@ UserF, TaxonomyF, Taxonomy, - VernacularName + VernacularName, + IUCNStatusF ) test_data_directory = os.path.join( @@ -30,6 +31,21 @@ def setUp(self): ) self.taxonomy = TaxonomyF.create() + IUCNStatusF.create( + category='NE', + national=True + ) + + IUCNStatusF.create( + category='NE', + national=False + ) + + IUCNStatusF.create( + category='NE', + national=False + ) + with open(os.path.join( test_data_directory, 'taxa_upload_family.csv' ), 'rb') as file: @@ -93,7 +109,6 @@ def test_taxa_upload(self, mock_fetch_all_species_from_gbif, mock_finish): canonical_name='Ecnomidae' ).biographic_distributions.filter( name='ANT', - doubtful=False ).exists() ) @@ -101,8 +116,7 @@ def test_taxa_upload(self, mock_fetch_all_species_from_gbif, mock_finish): Taxonomy.objects.get( canonical_name='Ecnomidae' ).biographic_distributions.filter( - name='AT', - doubtful=True + name='AT (?)', ).exists() )