From e1c07427ec69271e206ecf5c7b615d1909dbd5a7 Mon Sep 17 00:00:00 2001 From: Kenzo-Hugo Hillion <kenzo-hugo.hillion1@pasteur.fr> Date: Thu, 12 Dec 2019 12:20:26 +0100 Subject: [PATCH] update model of eggnog for different versions --- backend/Pipfile | 1 + backend/Pipfile.lock | 12 ++++++-- backend/metagenedb/api/catalog/urls.py | 2 +- .../metagenedb/api/catalog/views/__init__.py | 2 +- .../metagenedb/api/catalog/views/function.py | 6 ++-- .../api/catalog/views/test_function.py | 4 +-- .../metagenedb/apps/catalog/admin/function.py | 9 +++--- .../metagenedb/apps/catalog/admin/taxonomy.py | 2 ++ .../apps/catalog/factory/__init__.py | 2 +- .../apps/catalog/factory/function.py | 7 +++-- .../commands/create_update_eggnog.py | 6 ++-- .../migrations/0016_add_eggnog_version.py | 28 +++++++++++++++++++ ...e_eggnog.py => 0017_rename_meta_eggnog.py} | 12 ++++---- .../apps/catalog/models/__init__.py | 2 +- .../apps/catalog/models/function.py | 13 ++++++--- .../apps/catalog/serializers/function.py | 8 +++--- .../common/utils/mocks/metagenedb.py | 2 +- backend/metagenedb/settings/django.py | 1 + .../scripts/populate_db/import_igc_data.py | 2 +- .../populate_db/test_import_igc_data.py | 8 +++--- 20 files changed, 89 insertions(+), 40 deletions(-) create mode 100644 backend/metagenedb/apps/catalog/migrations/0016_add_eggnog_version.py rename backend/metagenedb/apps/catalog/migrations/{0016_rename_eggnog.py => 0017_rename_meta_eggnog.py} (53%) diff --git a/backend/Pipfile b/backend/Pipfile index 248e6dc..99a30ee 100644 --- a/backend/Pipfile +++ b/backend/Pipfile @@ -59,6 +59,7 @@ python-slugify = "*" marshmallow = "*" django-pandas = "*" bioapi = {git = "https://github.com/khillion/bioapi.git"} +django-admin-list-filter-dropdown = "*" [requires] python_version = "3.7" diff --git a/backend/Pipfile.lock b/backend/Pipfile.lock index 86dcc9a..57d5111 100644 --- a/backend/Pipfile.lock +++ b/backend/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "c448dca73004a15b2c0d65f4ff1e2b2da1aac4d1439a0be2adf97531783af899" + "sha256": "57d6d564aa9c1a9f750c89666f2191d1c5036bfa413119cb26f92719fbe48a6e" }, "pipfile-spec": 6, "requires": { @@ -65,6 +65,14 @@ "index": "pypi", "version": "==3.0" }, + "django-admin-list-filter-dropdown": { + "hashes": [ + "sha256:07cd37b6a9be1b08f11d4a92957c69b67bc70b1f87a2a7d4ae886c93ea51eb53", + "sha256:bf1b48bab9772dad79db71efef17e78782d4f2421444d5e49bb10e0da71cd6bb" + ], + "index": "pypi", + "version": "==1.0.3" + }, "django-cors-headers": { "hashes": [ "sha256:84933651fbbde8f2bc084bef2f077b79db1ec1389432f21dd661eaae6b3d6a95", @@ -403,7 +411,7 @@ "sha256:5b26757dc6f79a3b7dc9fab95359328d5747fcb2409d331ea66d0272b90ab2a0", "sha256:8b995ffe925347a2138d7ac0fe77155e4311a0ea6d6da4f5128fe4b3cbe5ed71" ], - "markers": "sys_platform == 'darwin'", + "markers": "platform_system == 'Darwin'", "version": "==0.1.0" }, "astroid": { diff --git a/backend/metagenedb/api/catalog/urls.py b/backend/metagenedb/api/catalog/urls.py index e4f6b6f..49c88b3 100644 --- a/backend/metagenedb/api/catalog/urls.py +++ b/backend/metagenedb/api/catalog/urls.py @@ -54,7 +54,7 @@ class CustomRouter(DefaultRouter): api_router = CustomRouter() api_router.register(r'functions', views.FunctionViewSet, basename='functions') api_router.register(r'kegg-orthologies', views.KeggOrthologyViewSet, basename='kegg-orthologies') -api_router.register(r'eggnogs', views.EggNOGv5ViewSet, basename='eggnogs') +api_router.register(r'eggnogs', views.EggNOGViewSet, basename='eggnogs') api_router.register(r'genes', views.GeneViewSet, basename='genes') api_router.register(r'taxonomy', views.TaxonomyViewSet, basename='taxonomy') diff --git a/backend/metagenedb/api/catalog/views/__init__.py b/backend/metagenedb/api/catalog/views/__init__.py index 0749101..03229a3 100644 --- a/backend/metagenedb/api/catalog/views/__init__.py +++ b/backend/metagenedb/api/catalog/views/__init__.py @@ -1,3 +1,3 @@ -from .function import EggNOGv5ViewSet, KeggOrthologyViewSet, FunctionViewSet # noqa +from .function import EggNOGViewSet, KeggOrthologyViewSet, FunctionViewSet # noqa from .gene import GeneViewSet # noqa from .taxonomy import TaxonomyViewSet # noqa diff --git a/backend/metagenedb/api/catalog/views/function.py b/backend/metagenedb/api/catalog/views/function.py index 9d1dc4c..3dcb685 100644 --- a/backend/metagenedb/api/catalog/views/function.py +++ b/backend/metagenedb/api/catalog/views/function.py @@ -7,7 +7,7 @@ from rest_framework.viewsets import ModelViewSet from metagenedb.api.catalog.filters import FunctionFilter from metagenedb.api.catalog.qparams_validators.function import FunctionQueryParams -from metagenedb.apps.catalog.models import EggNOGv5, Function, KeggOrthology +from metagenedb.apps.catalog.models import EggNOG, Function, KeggOrthology from metagenedb.apps.catalog.serializers import EggNOGSerializer, FunctionSerializer, KeggOrthologySerializer from metagenedb.common.utils.external_api.togows import GetFunctionExternalInfo @@ -57,7 +57,7 @@ class KeggOrthologyViewSet(ModelViewSet): return Response(returned_data) -class EggNOGv5ViewSet(ModelViewSet): - queryset = EggNOGv5.objects.all() +class EggNOGViewSet(ModelViewSet): + queryset = EggNOG.objects.all() serializer_class = EggNOGSerializer lookup_field = 'function_id' diff --git a/backend/metagenedb/api/catalog/views/test_function.py b/backend/metagenedb/api/catalog/views/test_function.py index 5734445..217e7b5 100644 --- a/backend/metagenedb/api/catalog/views/test_function.py +++ b/backend/metagenedb/api/catalog/views/test_function.py @@ -2,7 +2,7 @@ from rest_framework.test import APITestCase import mock -from metagenedb.apps.catalog.factory import EggNOGv5Factory, KeggOrthologyFactory +from metagenedb.apps.catalog.factory import EggNOGFactory, KeggOrthologyFactory from metagenedb.common.utils.mocks.metagenedb import ( MetageneDBCatalogFunctionAPIMock, MetageneDBCatalogKeggOrthologyAPIMock ) @@ -14,7 +14,7 @@ class TestKeggOrthologyViewSet(APITestCase): self.function_api = MetageneDBCatalogFunctionAPIMock(self.client) self.kegg_ortho_api = MetageneDBCatalogKeggOrthologyAPIMock(self.client) self.kegg_function = KeggOrthologyFactory.create() - self.eggnog_function = EggNOGv5Factory.create() + self.eggnog_function = EggNOGFactory.create() def test_retrieve(self): for function in [self.kegg_function, self.eggnog_function]: diff --git a/backend/metagenedb/apps/catalog/admin/function.py b/backend/metagenedb/apps/catalog/admin/function.py index c6a675b..a3df9e8 100644 --- a/backend/metagenedb/apps/catalog/admin/function.py +++ b/backend/metagenedb/apps/catalog/admin/function.py @@ -1,6 +1,6 @@ from django.contrib import admin -from metagenedb.apps.catalog.models import EggNOGv5, EggNOGFunctionalCategory, Function, KeggOrthology +from metagenedb.apps.catalog.models import EggNOG, EggNOGFunctionalCategory, Function, KeggOrthology @admin.register(KeggOrthology) @@ -17,10 +17,11 @@ class FunctionAdmin(admin.ModelAdmin): search_fields = ('function_id',) -@admin.register(EggNOGv5) -class EggNOGv5Admin(admin.ModelAdmin): +@admin.register(EggNOG) +class EggNOGAdmin(admin.ModelAdmin): - list_display = ('function_id', 'name', 'get_functional_categories') + list_display = ('function_id', 'name', 'get_functional_categories', 'version') + list_filter = ('version',) search_fields = ('function_id', 'name') def get_functional_categories(self, obj): diff --git a/backend/metagenedb/apps/catalog/admin/taxonomy.py b/backend/metagenedb/apps/catalog/admin/taxonomy.py index 633f57b..445228d 100644 --- a/backend/metagenedb/apps/catalog/admin/taxonomy.py +++ b/backend/metagenedb/apps/catalog/admin/taxonomy.py @@ -1,4 +1,5 @@ from django.contrib import admin +from django_admin_listfilter_dropdown.filters import DropdownFilter from metagenedb.apps.catalog.models import Taxonomy @@ -10,4 +11,5 @@ class TaxonomyAdmin(admin.ModelAdmin): 'tax_id', 'name', 'rank', 'superkingdom', 'kingdom', 'phylum', 'class_rank', 'order', 'family', 'genus', 'species', ) + list_filter = (('rank', DropdownFilter),) search_fields = ('tax_id', 'name') diff --git a/backend/metagenedb/apps/catalog/factory/__init__.py b/backend/metagenedb/apps/catalog/factory/__init__.py index a02fda0..d7b5b14 100644 --- a/backend/metagenedb/apps/catalog/factory/__init__.py +++ b/backend/metagenedb/apps/catalog/factory/__init__.py @@ -1,3 +1,3 @@ -from .function import EggNOGv5Factory, FunctionFactory, KeggOrthologyFactory # noqa +from .function import EggNOGFactory, FunctionFactory, KeggOrthologyFactory # noqa from .gene import GeneFactory # noqa from .taxonomy import TaxonomyFactory # noqa diff --git a/backend/metagenedb/apps/catalog/factory/function.py b/backend/metagenedb/apps/catalog/factory/function.py index fc523e8..1ab878b 100644 --- a/backend/metagenedb/apps/catalog/factory/function.py +++ b/backend/metagenedb/apps/catalog/factory/function.py @@ -8,6 +8,7 @@ from .fuzzy_base import FuzzyLowerText faker = Factory.create() SELECTED_SOURCE = [i[0] for i in models.Function.SOURCE_CHOICES] +EGGNOG_VERSIONS = [i[0] for i in models.EggNOG.VERSION_CHOICES] class BaseFunctionFactory(DjangoModelFactory): @@ -22,9 +23,11 @@ class FunctionFactory(BaseFunctionFactory): function_id = FuzzyLowerText(prefix='function-', length=15) -class EggNOGv5Factory(BaseFunctionFactory): +class EggNOGFactory(BaseFunctionFactory): class Meta: - model = models.EggNOGv5 + model = models.EggNOG + + version = fuzzy.FuzzyChoice(EGGNOG_VERSIONS) class KeggOrthologyFactory(BaseFunctionFactory): diff --git a/backend/metagenedb/apps/catalog/management/commands/create_update_eggnog.py b/backend/metagenedb/apps/catalog/management/commands/create_update_eggnog.py index 3c6750f..91fcbfb 100644 --- a/backend/metagenedb/apps/catalog/management/commands/create_update_eggnog.py +++ b/backend/metagenedb/apps/catalog/management/commands/create_update_eggnog.py @@ -3,7 +3,7 @@ import logging from django.core.management.base import BaseCommand from django.core.exceptions import ValidationError -from metagenedb.apps.catalog.models import EggNOGv5, EggNOGFunctionalCategory +from metagenedb.apps.catalog.models import EggNOG, EggNOGFunctionalCategory from metagenedb.common.utils.chunks import file_len from metagenedb.common.utils.parsers import EggNOGAnnotationLineParser @@ -43,14 +43,14 @@ class ImportEggNOG(object): payload = {k: v for k, v in eggnog_dict.items() if v != ""} eggnog = None try: - eggnog = EggNOGv5(**payload) + eggnog = EggNOG(**payload) eggnog.full_clean() eggnog.save() self.created_count += 1 except ValidationError as validation_error: if 'function_id' in validation_error.error_dict.keys(): try: - eggnog = EggNOGv5.objects.get(function_id=payload.get('function_id')) + eggnog = EggNOG.objects.get(function_id=payload.get('function_id')) for k, v in payload.items(): setattr(eggnog, k, v) eggnog.full_clean() diff --git a/backend/metagenedb/apps/catalog/migrations/0016_add_eggnog_version.py b/backend/metagenedb/apps/catalog/migrations/0016_add_eggnog_version.py new file mode 100644 index 0000000..b92f5b5 --- /dev/null +++ b/backend/metagenedb/apps/catalog/migrations/0016_add_eggnog_version.py @@ -0,0 +1,28 @@ +# Generated by Django 3.0 on 2019-12-12 10:46 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('catalog', '0015_m2m_func_cat_eggnog'), + ] + + operations = [ + migrations.AlterModelOptions( + name='eggnog', + options={}, + ), + migrations.AddField( + model_name='eggnog', + name='version', + field=models.CharField(choices=[('3.0', '3.0'), ('5.0', '5.0')], default=5.0, max_length=5), + preserve_default=False, + ), + migrations.AlterField( + model_name='eggnog', + name='functional_categories', + field=models.ManyToManyField(to='catalog.EggNOGFunctionalCategory'), + ), + ] diff --git a/backend/metagenedb/apps/catalog/migrations/0016_rename_eggnog.py b/backend/metagenedb/apps/catalog/migrations/0017_rename_meta_eggnog.py similarity index 53% rename from backend/metagenedb/apps/catalog/migrations/0016_rename_eggnog.py rename to backend/metagenedb/apps/catalog/migrations/0017_rename_meta_eggnog.py index bc77106..ad200e6 100644 --- a/backend/metagenedb/apps/catalog/migrations/0016_rename_eggnog.py +++ b/backend/metagenedb/apps/catalog/migrations/0017_rename_meta_eggnog.py @@ -1,4 +1,4 @@ -# Generated by Django 3.0 on 2019-12-11 22:07 +# Generated by Django 3.0 on 2019-12-12 11:12 from django.db import migrations, models @@ -6,16 +6,16 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('catalog', '0015_m2m_func_cat_eggnog'), + ('catalog', '0016_add_eggnog_version'), ] operations = [ - migrations.RenameModel( - old_name='EggNog', - new_name='EggNOGv5', + migrations.AlterModelOptions( + name='eggnog', + options={'verbose_name': 'EggNOG', 'verbose_name_plural': 'EggNOGs'}, ), migrations.AlterField( - model_name='eggnogv5', + model_name='eggnog', name='functional_categories', field=models.ManyToManyField(to='catalog.EggNOGFunctionalCategory'), ), diff --git a/backend/metagenedb/apps/catalog/models/__init__.py b/backend/metagenedb/apps/catalog/models/__init__.py index 50aa3dd..795bdeb 100644 --- a/backend/metagenedb/apps/catalog/models/__init__.py +++ b/backend/metagenedb/apps/catalog/models/__init__.py @@ -1,3 +1,3 @@ -from .function import EggNOGv5, EggNOGFunctionalCategory, Function, KeggOrthology # noqa +from .function import EggNOG, EggNOGFunctionalCategory, Function, KeggOrthology # noqa from .gene import Gene, GeneFunction # noqa from .taxonomy import Taxonomy # noqa diff --git a/backend/metagenedb/apps/catalog/models/function.py b/backend/metagenedb/apps/catalog/models/function.py index aa10577..45b6fe9 100644 --- a/backend/metagenedb/apps/catalog/models/function.py +++ b/backend/metagenedb/apps/catalog/models/function.py @@ -56,14 +56,19 @@ class EggNOGFunctionalCategory(models.Model): verbose_name_plural = "EggNOG functional categories" -class EggNOGv5(Function): +class EggNOG(Function): SOURCE = 'eggnog' + VERSION_CHOICES = [ + ('3.0', '3.0'), + ('5.0', '5.0') + ] functional_categories = models.ManyToManyField(EggNOGFunctionalCategory) + version = models.CharField(max_length=5, choices=VERSION_CHOICES) def __init__(self, *args, **kwargs): - super(EggNOGv5, self).__init__(source=self.SOURCE, *args, **kwargs) + super(EggNOG, self).__init__(source=self.SOURCE, *args, **kwargs) class Meta: - verbose_name = "EggNOG v5.0" - verbose_name_plural = "EggNOGs v5.0" + verbose_name = "EggNOG" + verbose_name_plural = "EggNOGs" diff --git a/backend/metagenedb/apps/catalog/serializers/function.py b/backend/metagenedb/apps/catalog/serializers/function.py index f937dd3..15cbe30 100644 --- a/backend/metagenedb/apps/catalog/serializers/function.py +++ b/backend/metagenedb/apps/catalog/serializers/function.py @@ -1,5 +1,5 @@ from rest_framework import serializers -from metagenedb.apps.catalog.models import EggNOGv5, Function, KeggOrthology +from metagenedb.apps.catalog.models import EggNOG, Function, KeggOrthology from .bulk_list import BulkListSerializer @@ -21,15 +21,15 @@ class FunctionSerializer(serializers.ModelSerializer): class EggNOGListSerializer(BulkListSerializer): class Meta: - model = EggNOGv5 + model = EggNOG class EggNOGSerializer(serializers.ModelSerializer): class Meta: - model = EggNOGv5 + model = EggNOG list_serializer_class = EggNOGListSerializer - fields = ('function_id', 'name', 'functional_categories') + fields = ('function_id', 'name', 'functional_categories', 'version') class KeggOrthologyListSerializer(BulkListSerializer): diff --git a/backend/metagenedb/common/utils/mocks/metagenedb.py b/backend/metagenedb/common/utils/mocks/metagenedb.py index ec8baee..c8e0185 100644 --- a/backend/metagenedb/common/utils/mocks/metagenedb.py +++ b/backend/metagenedb/common/utils/mocks/metagenedb.py @@ -90,5 +90,5 @@ class MetageneDBCatalogKeggOrthologyAPIMock(MetageneDBCatalogFunctionAPIMock): REVERSE_PATH = 'catalog:v1:kegg-orthologies' -class MetageneDBCatalogEggNOGv5APIMock(MetageneDBCatalogFunctionAPIMock): +class MetageneDBCatalogEggNOGAPIMock(MetageneDBCatalogFunctionAPIMock): REVERSE_PATH = 'catalog:v1:eggnogs' diff --git a/backend/metagenedb/settings/django.py b/backend/metagenedb/settings/django.py index 02ddd74..fd14467 100644 --- a/backend/metagenedb/settings/django.py +++ b/backend/metagenedb/settings/django.py @@ -21,6 +21,7 @@ INSTALLED_APPS = [ 'django_filters', 'corsheaders', 'drf_yasg', + 'django_admin_listfilter_dropdown', ] MIDDLEWARE = [ diff --git a/backend/scripts/populate_db/import_igc_data.py b/backend/scripts/populate_db/import_igc_data.py index a0d9d68..c95c409 100755 --- a/backend/scripts/populate_db/import_igc_data.py +++ b/backend/scripts/populate_db/import_igc_data.py @@ -10,7 +10,7 @@ from bioapi import ( MetageneDBCatalogGeneAPI, MetageneDBCatalogTaxonomyAPI, MetageneDBCatalogKeggOrthologyAPI, - MetageneDBCatalogEggNogAPI + MetageneDBCatalogEggNogAPI, ) from requests.exceptions import HTTPError from slugify import slugify diff --git a/backend/scripts/populate_db/test_import_igc_data.py b/backend/scripts/populate_db/test_import_igc_data.py index 9960d02..ba76a09 100644 --- a/backend/scripts/populate_db/test_import_igc_data.py +++ b/backend/scripts/populate_db/test_import_igc_data.py @@ -4,13 +4,13 @@ from rest_framework.test import APITestCase from metagenedb.common.utils.mocks.metagenedb import ( MetageneDBCatalogTaxonomyAPIMock, - MetageneDBCatalogEggNOGv5APIMock, + MetageneDBCatalogEggNOGAPIMock, MetageneDBCatalogKeggOrthologyAPIMock ) from metagenedb.apps.catalog.factory import ( TaxonomyFactory, KeggOrthologyFactory, - EggNOGv5Factory + EggNOGFactory ) from scripts.populate_db.import_igc_data import ImportIGCGenes @@ -302,12 +302,12 @@ class TestBuildBuildFunctionCatalog(APITestCase): @classmethod def setUpTestData(cls): cls.keggs = KeggOrthologyFactory.create_batch(100) - cls.eggnogs = EggNOGv5Factory.create_batch(100) + cls.eggnogs = EggNOGFactory.create_batch(100) def setUp(self): self.import_igc_genes = ImportIGCGenes('test', 'test_url', 'test_token') self.kegg_api_mock = MetageneDBCatalogKeggOrthologyAPIMock(self.client) - self.eggnog_api_mock = MetageneDBCatalogEggNOGv5APIMock(self.client) + self.eggnog_api_mock = MetageneDBCatalogEggNOGAPIMock(self.client) self.import_igc_genes.metagenedb_kegg_api = self.kegg_api_mock self.import_igc_genes.metagenedb_eggnog_api = self.eggnog_api_mock -- GitLab