From 40a2ecaa7e1af283e769e0798f41675b08d16a8a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Herv=C3=A9=20=20MENAGER?= <herve.menager@pasteur.fr>
Date: Mon, 12 Jun 2017 16:08:27 +0200
Subject: [PATCH] refactor model data ws retrieval in AutoFillableModel

Former-commit-id: 6ce2b8f1ac3abdb736089b328505f7ed0992fa61
---
 .../management/commands/import_v1_data.py     |  6 +--
 ippisite/ippidb/models.py                     | 47 ++++++++++++-------
 2 files changed, 33 insertions(+), 20 deletions(-)

diff --git a/ippisite/ippidb/management/commands/import_v1_data.py b/ippisite/ippidb/management/commands/import_v1_data.py
index 30a3cab0..41c0a5b7 100644
--- a/ippisite/ippidb/management/commands/import_v1_data.py
+++ b/ippisite/ippidb/management/commands/import_v1_data.py
@@ -107,7 +107,7 @@ class Command(BaseCommand):
                     else:
                         b.source = 'PT'
                     b.id_source = row[2]
-                    b.save()
+                    b.save(autofill=True)
                 except Exception as e:
                     self.stdout.write(self.style.ERROR('Failed inserting {}'.format(row[2])))
                 else:
@@ -125,7 +125,7 @@ class Command(BaseCommand):
                 try:
                     p = Protein()
                     p.uniprot_id = row[1]
-                    p.save()
+                    p.save(autofill=True)
                 except Exception as e:
                     if options['stoponfail']:
                         import traceback
@@ -145,7 +145,7 @@ class Command(BaseCommand):
                     p = Domain()
                     p.pfam_acc = row[2]
                     p.domain_family = row[4]
-                    p.save()
+                    p.save(autofill=True)
                 except Exception as e:
                     if options['stoponfail']:
                         import traceback
diff --git a/ippisite/ippidb/models.py b/ippisite/ippidb/models.py
index 43496e76..5cc9d3f7 100644
--- a/ippisite/ippidb/models.py
+++ b/ippisite/ippidb/models.py
@@ -4,7 +4,24 @@ from django.db import models
 
 from .ws import get_pubmed_info, get_epo_info, get_uniprot_info, get_taxonomy_info, get_go_info, get_pfam_info
 
-class Bibliography(models.Model):
+class AutoFillableModel(models.Model):
+    """
+    AutoFillableModel makes it possible to automatically fill model fields from
+    external sources in the autofill() method
+    The save method allows to either include autofill or not. in autofill kwarg is
+    set to True, save() will first call autofill(), otherwise it won't
+    """
+
+    class Meta:
+        abstract = True
+
+    def save(self, *args, **kwargs):
+        if kwargs.get('autofill') is True:
+            self.autofill()
+        super(AutoFillableModel, self).save(*args, **kwargs)
+
+
+class Bibliography(AutoFillableModel):
     """
     Bibliography data table
     """
@@ -26,7 +43,7 @@ class Bibliography(models.Model):
     pharmacokinetic = models.BooleanField('pharmacokinetic study performed', default=False)
     xray = models.BooleanField('contains xray data', default=False)
 
-    def save(self, *args, **kwargs):
+    def autofill(self):
         if self.source == 'PM':
             info = get_pubmed_info(self.id_source)
         else:
@@ -35,7 +52,6 @@ class Bibliography(models.Model):
         self.journal_name = info['journal_name']
         self.authors_list = info['authors_list']
         self.biblio_year = info['biblio_year']
-        super(Bibliography, self).save(*args, **kwargs)
 
     class Meta:
         verbose_name_plural = "bibliographies"
@@ -44,14 +60,13 @@ class Bibliography(models.Model):
         return '{}, {}'.format(self.source, self.id_source)
 
 
-class Taxonomy(models.Model):
+class Taxonomy(AutoFillableModel):
     taxonomy_id = models.DecimalField('NCBI TaxID', unique=True, max_digits=9, decimal_places=0)
     name = models.CharField('Organism name', max_length=200)
 
-    def save(self, *args, **kwargs):
+    def autofill(self):
         info = get_taxonomy_info(self.taxonomy_id)
         self.name = info['scientific_name']
-        super(Taxonomy, self).save(*args, **kwargs)
 
     def __str__(self):
         return self.name
@@ -59,19 +74,18 @@ class Taxonomy(models.Model):
     class Meta:
         verbose_name_plural = "taxonomies"
 
-class MolecularFunction(models.Model):
+class MolecularFunction(AutoFillableModel):
     go_id = models.CharField('Gene Ontology ID', unique=True, max_length=10) # GO term id format: 'GO:0000000' 
     description = models.CharField('description', max_length=500)
 
-    def save(self, *args, **kwargs):
+    def autofill(self):
         info = get_go_info(self.go_id)
         self.description = info['label']
-        super(MolecularFunction, self).save(*args, **kwargs)
 
     def __str__(self):
         return self.description
 
-class Protein(models.Model):
+class Protein(AutoFillableModel):
     uniprot_id = models.CharField('Uniprot ID', unique=True, max_length=10)
     recommended_name_long = models.CharField('Uniprot Recommended Name (long)', max_length=75)
     short_name = models.CharField('Short name', max_length=50)
@@ -80,7 +94,7 @@ class Protein(models.Model):
     organism = models.ForeignKey('Taxonomy')
     molecular_functions = models.ManyToManyField(MolecularFunction)
 
-    def save(self, *args, **kwargs):
+    def autofill(self):
         info = get_uniprot_info(self.uniprot_id)
         self.recommended_name_long = info['recommended_name']
         self.gene_name = info['gene']
@@ -90,32 +104,31 @@ class Protein(models.Model):
         except Taxonomy.DoesNotExist:
             taxonomy = Taxonomy()
             taxonomy.taxonomy_id = info['organism']
-            taxonomy.save()
+            taxonomy.save(autofill=True)
         self.organism = taxonomy
-        super(Protein, self).save(*args, **kwargs)
+        #super(Protein, self).save(*args, **kwargs)
         for go_id in info['molecular_functions']:
             try:
                 mol_function = MolecularFunction.objects.get(go_id=go_id)
             except MolecularFunction.DoesNotExist:
                 mol_function = MolecularFunction()
                 mol_function.go_id = go_id
-                mol_function.save()
+                mol_function.save(autofill=True)
             self.molecular_functions.add(mol_function)
 
     def __str__(self):
         return '{} ({})'.format(self.uniprot_id, self.recommended_name_long)
 
-class Domain(models.Model):
+class Domain(AutoFillableModel):
     pfam_acc = models.CharField('Pfam Accession', max_length=10, unique=True) 
     pfam_id = models.CharField('Pfam Family Identifier', max_length=20) 
     pfam_description = models.CharField('Pfam Description', max_length=100)
     domain_family = models.CharField('Domain family', max_length=25)  #TODO: what is this field? check database contents
 
-    def save(self, *args, **kwargs):
+    def autofill(self):
         info = get_pfam_info(self.pfam_acc)
         self.pfam_id = info['id']
         self.pfam_description = info['description']
-        super(Domain, self).save(*args, **kwargs)
 
     def __str__(self):
         return '{} ({}-{})'.format(self.pfam_acc, self.pfam_id, self.pfam_description)
-- 
GitLab