diff --git a/backend/metagenedb/apps/catalog/serializers/asymetricslugrelatedfield.py b/backend/metagenedb/apps/catalog/serializers/asymetricslugrelatedfield.py new file mode 100644 index 0000000000000000000000000000000000000000..29a4fe5c7366b2df732fc6a053e4320e8941f784 --- /dev/null +++ b/backend/metagenedb/apps/catalog/serializers/asymetricslugrelatedfield.py @@ -0,0 +1,38 @@ +from collections import OrderedDict + +from rest_framework import serializers + + +class AsymetricSlugRelatedField(serializers.SlugRelatedField): + + def to_representation(self, value): + return self.serializer_class(value).data + + # Get choices used by DRF autodoc and expect to_representation() to return an ID + # We overload to use item.pk instead of to_representation() + def get_choices(self, cutoff=None): + queryset = self.get_queryset() + if queryset is None: + return {} + + if cutoff is not None: + queryset = queryset[:cutoff] + + return OrderedDict([ + ( + item.pk, + self.display_value(item) + ) + for item in queryset + ]) + + # DRF skip validations when it only has id, we deactivate that + def use_pk_only_optimization(self): + return False + + @classmethod + def from_serializer(cls, serializer, name=None, *args, **kwargs): + if name is None: + name = f"{serializer.__class__.__name__}AsymetricSlugAutoField" + + return type(name, (cls,), {"serializer_class": serializer})(*args, **kwargs) diff --git a/backend/metagenedb/apps/catalog/serializers/gene.py b/backend/metagenedb/apps/catalog/serializers/gene.py index a03e62d6167c3f17b83dfaff6ff037ebee9ec3c1..f32a9dd8f55d2ad0dda1310dfe31c624055cc0cb 100644 --- a/backend/metagenedb/apps/catalog/serializers/gene.py +++ b/backend/metagenedb/apps/catalog/serializers/gene.py @@ -5,7 +5,11 @@ from rest_framework import serializers from rest_framework.utils import model_meta from metagenedb.apps.catalog.models import Function, Gene, GeneFunction, Taxonomy +from .asymetricslugrelatedfield import AsymetricSlugRelatedField from .bulk_list import BulkListSerializer +from .function import FunctionSerializer +from .taxonomy import SimpleTaxonomySerializer + _LOGGER = logging.getLogger(__name__) @@ -48,13 +52,15 @@ class GeneListSerializer(BulkListSerializer): class GeneSerializer(serializers.ModelSerializer): - functions = serializers.SlugRelatedField( + functions = AsymetricSlugRelatedField.from_serializer( + FunctionSerializer, queryset=Function.objects.all(), slug_field='function_id', many=True, required=False, ) - taxonomy = serializers.SlugRelatedField( + taxonomy = AsymetricSlugRelatedField.from_serializer( + SimpleTaxonomySerializer, queryset=Taxonomy.objects.all(), slug_field='tax_id', required=False, diff --git a/backend/metagenedb/apps/catalog/serializers/taxonomy.py b/backend/metagenedb/apps/catalog/serializers/taxonomy.py index 4728809cc914c14ec4f002f947f3ac1761852ffc..50c28b7300d26dd19963bbac6c5bb058996e3c00 100644 --- a/backend/metagenedb/apps/catalog/serializers/taxonomy.py +++ b/backend/metagenedb/apps/catalog/serializers/taxonomy.py @@ -1,9 +1,17 @@ from rest_framework import serializers from metagenedb.apps.catalog.models import Taxonomy +from .asymetricslugrelatedfield import AsymetricSlugRelatedField from .bulk_list import BulkListSerializer +class SimpleTaxonomySerializer(serializers.ModelSerializer): + + class Meta: + model = Taxonomy + fields = ('tax_id', 'name') + + class TaxonomyListSerializer(BulkListSerializer): class Meta: @@ -12,48 +20,57 @@ class TaxonomyListSerializer(BulkListSerializer): class TaxonomySerializer(serializers.ModelSerializer): rank = serializers.CharField(required=False) - parent_tax_id = serializers.SlugRelatedField( + parent_tax_id = AsymetricSlugRelatedField.from_serializer( + SimpleTaxonomySerializer, queryset=Taxonomy.objects.all(), slug_field='tax_id', source='parent', required=False, ) - superkingdom = serializers.SlugRelatedField( + superkingdom = AsymetricSlugRelatedField.from_serializer( + SimpleTaxonomySerializer, queryset=Taxonomy.objects.all(), slug_field='tax_id', required=False ) - kingdom = serializers.SlugRelatedField( + kingdom = AsymetricSlugRelatedField.from_serializer( + SimpleTaxonomySerializer, queryset=Taxonomy.objects.all(), slug_field='tax_id', required=False ) - phylum = serializers.SlugRelatedField( + phylum = AsymetricSlugRelatedField.from_serializer( + SimpleTaxonomySerializer, queryset=Taxonomy.objects.all(), slug_field='tax_id', required=False ) - class_rank = serializers.SlugRelatedField( + class_rank = AsymetricSlugRelatedField.from_serializer( + SimpleTaxonomySerializer, queryset=Taxonomy.objects.all(), slug_field='tax_id', required=False ) - order = serializers.SlugRelatedField( + order = AsymetricSlugRelatedField.from_serializer( + SimpleTaxonomySerializer, queryset=Taxonomy.objects.all(), slug_field='tax_id', required=False ) - family = serializers.SlugRelatedField( + family = AsymetricSlugRelatedField.from_serializer( + SimpleTaxonomySerializer, queryset=Taxonomy.objects.all(), slug_field='tax_id', required=False ) - genus = serializers.SlugRelatedField( + genus = AsymetricSlugRelatedField.from_serializer( + SimpleTaxonomySerializer, queryset=Taxonomy.objects.all(), slug_field='tax_id', required=False ) - species = serializers.SlugRelatedField( + species = AsymetricSlugRelatedField.from_serializer( + SimpleTaxonomySerializer, queryset=Taxonomy.objects.all(), slug_field='tax_id', required=False diff --git a/frontend/src/components/TaxonomyCard.vue b/frontend/src/components/TaxonomyCard.vue index 0f489afc6d28575fe4900004b35d40f7d7e6646b..1413b41df696a57ead3c4278e38df423da7e6d92 100644 --- a/frontend/src/components/TaxonomyCard.vue +++ b/frontend/src/components/TaxonomyCard.vue @@ -20,7 +20,7 @@ <v-list-tile v-if="item.content" :key="item.title"> <v-list-tile-content :key="item.title"> <v-list-tile-title v-html="item.title"></v-list-tile-title> - <v-list-tile-sub-title v-html="item.content"></v-list-tile-sub-title> + <v-list-tile-sub-title v-html="item.content.name"></v-list-tile-sub-title> </v-list-tile-content> </v-list-tile> </template> diff --git a/frontend/src/views/GeneDetail.vue b/frontend/src/views/GeneDetail.vue index 67b16b62fe52bd0e60e48a1f8717558bd7d8754d..4f812a931bf406b702a68744b9c3502661039e66 100644 --- a/frontend/src/views/GeneDetail.vue +++ b/frontend/src/views/GeneDetail.vue @@ -90,8 +90,8 @@ export default { content: response.data.length, }, ]; - this.kegg_id = response.data.functions[0]; - this.taxonomy_id = response.data.taxonomy; + this.kegg_id = response.data.functions[0].function_id; + this.taxonomy_id = response.data.taxonomy.tax_id; }) .catch((error) => { console.log(error);