From d3338b458066d54a4764871cb52c5a98fc7370f5 Mon Sep 17 00:00:00 2001 From: Zoran Sinnema Date: Mon, 9 Jan 2023 15:45:37 +0100 Subject: [PATCH] #51 refactor: NoteTag to Tag --- backend/composer/admin.py | 8 +-- .../commands/ingest_nlp_sentence.py | 4 +- ...e_notetag_tag_remove_note_tags_and_more.py | 55 +++++++++++++++++++ .../migrations/0034_alter_tag_options.py | 17 ++++++ backend/composer/models.py | 20 +++---- backend/composer/serializers.py | 9 ++- backend/composer/urls.py | 10 ++-- backend/composer/views.py | 22 ++++---- 8 files changed, 108 insertions(+), 37 deletions(-) create mode 100644 backend/composer/migrations/0033_rename_notetag_tag_remove_note_tags_and_more.py create mode 100644 backend/composer/migrations/0034_alter_tag_options.py diff --git a/backend/composer/admin.py b/backend/composer/admin.py index 8b317ad1..8931cca2 100644 --- a/backend/composer/admin.py +++ b/backend/composer/admin.py @@ -15,7 +15,7 @@ ConnectivityStatement, Doi, Note, - NoteTag, + Tag, Profile, Provenance, Specie, @@ -43,7 +43,7 @@ class DoiInline(admin.StackedInline): extra = 1 -class DoiiNestedInline(nested_admin.NestedStackedInline): +class DoiNestedInline(nested_admin.NestedStackedInline): model = Doi extra = 1 @@ -65,7 +65,7 @@ class ConnectivityStatementInline(nested_admin.NestedStackedInline): model = ConnectivityStatement extra = 1 fields = ("provenance", "knowledge_statement") - inlines = (DoiiNestedInline,) + inlines = (DoiNestedInline,) # Define a new User admin @@ -164,6 +164,6 @@ def pmcid(self, obj): admin.site.register(AnatomicalEntity, AnatomicalEntityAdmin) admin.site.register(AnsDivision) admin.site.register(ConnectivityStatement, ConnectivityStatementAdmin) -admin.site.register(NoteTag) +admin.site.register(Tag) admin.site.register(Provenance, ProvenanceAdmin) admin.site.register(Specie) diff --git a/backend/composer/management/commands/ingest_nlp_sentence.py b/backend/composer/management/commands/ingest_nlp_sentence.py index 32620172..5a745954 100644 --- a/backend/composer/management/commands/ingest_nlp_sentence.py +++ b/backend/composer/management/commands/ingest_nlp_sentence.py @@ -34,9 +34,7 @@ def handle(self, *args, **options): out_of_scope = row[OUT_OF_SCOPE].lower() if out_of_scope and out_of_scope.lower() == "yes": # skip out of scope records - self.stdout.write( - f"{rowid}: out of scope." - ) + self.stdout.write(f"{rowid}: out of scope.") continue rowid = row[ID] pmid = row[PMID] if row[PMID] != "0" else None diff --git a/backend/composer/migrations/0033_rename_notetag_tag_remove_note_tags_and_more.py b/backend/composer/migrations/0033_rename_notetag_tag_remove_note_tags_and_more.py new file mode 100644 index 00000000..cd863621 --- /dev/null +++ b/backend/composer/migrations/0033_rename_notetag_tag_remove_note_tags_and_more.py @@ -0,0 +1,55 @@ +# Generated by Django 4.1.4 on 2023-01-09 14:36 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ("composer", "0032_remove_provenance_provenance_pmid_pmcd_unique"), + ] + + operations = [ + migrations.RenameModel( + old_name="NoteTag", + new_name="Tag", + ), + migrations.RemoveField( + model_name="note", + name="tags", + ), + migrations.AddField( + model_name="connectivitystatement", + name="tags", + field=models.ManyToManyField(to="composer.tag", verbose_name="Tags"), + ), + migrations.AddField( + model_name="provenance", + name="tags", + field=models.ManyToManyField(to="composer.tag", verbose_name="Tags"), + ), + migrations.AlterField( + model_name="connectivitystatement", + name="path", + field=models.ManyToManyField( + blank=True, through="composer.Via", to="composer.anatomicalentity" + ), + ), + migrations.AlterField( + model_name="via", + name="anatomical_entity", + field=models.ForeignKey( + on_delete=django.db.models.deletion.DO_NOTHING, + to="composer.anatomicalentity", + ), + ), + migrations.AlterField( + model_name="via", + name="connectivity_statement", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="composer.connectivitystatement", + ), + ), + ] diff --git a/backend/composer/migrations/0034_alter_tag_options.py b/backend/composer/migrations/0034_alter_tag_options.py new file mode 100644 index 00000000..2b9dedd7 --- /dev/null +++ b/backend/composer/migrations/0034_alter_tag_options.py @@ -0,0 +1,17 @@ +# Generated by Django 4.1.4 on 2023-01-09 14:45 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("composer", "0033_rename_notetag_tag_remove_note_tags_and_more"), + ] + + operations = [ + migrations.AlterModelOptions( + name="tag", + options={"ordering": ["tag"], "verbose_name_plural": "Tags"}, + ), + ] diff --git a/backend/composer/models.py b/backend/composer/models.py index 431d48d1..1b2af86b 100644 --- a/backend/composer/models.py +++ b/backend/composer/models.py @@ -56,8 +56,8 @@ class Meta: verbose_name_plural = "Anatomical Entities" -class NoteTag(models.Model): - """Note Tag""" +class Tag(models.Model): + """Tag""" tag = models.CharField(max_length=200, db_index=True, unique=True) @@ -66,7 +66,7 @@ def __str__(self): class Meta: ordering = ["tag"] - verbose_name_plural = "Note Tags" + verbose_name_plural = "Tags" class Provenance(models.Model): @@ -77,6 +77,7 @@ class Provenance(models.Model): state = FSMField(default=ProvenanceState.OPEN, protected=True) pmid = models.BigIntegerField(db_index=True, null=True, blank=True) pmcid = models.CharField(max_length=10, db_index=True, null=True, blank=True) + tags = models.ManyToManyField(Tag, verbose_name="Tags") owner = models.ForeignKey( User, verbose_name="Triage Operator", @@ -161,8 +162,6 @@ class Meta: ] - - class Via(models.Model): """Via""" @@ -170,9 +169,7 @@ class Via(models.Model): "ConnectivityStatement", on_delete=models.CASCADE, ) - anatomical_entity = models.ForeignKey( - AnatomicalEntity, on_delete=models.DO_NOTHING - ) + anatomical_entity = models.ForeignKey(AnatomicalEntity, on_delete=models.DO_NOTHING) ordering = models.PositiveIntegerField( default=0, blank=False, @@ -217,9 +214,7 @@ class ConnectivityStatement(models.Model): owner = models.ForeignKey( User, verbose_name="Curator", on_delete=models.DO_NOTHING, null=True, blank=True ) - path = models.ManyToManyField( - AnatomicalEntity, through=Via, blank=True - ) + path = models.ManyToManyField(AnatomicalEntity, through=Via, blank=True) laterality = models.CharField( max_length=20, default=Laterality.UNKNOWN, choices=Laterality.choices ) @@ -234,6 +229,7 @@ class ConnectivityStatement(models.Model): blank=True, ) species = models.ManyToManyField(Specie, verbose_name="Species", blank=True) + tags = models.ManyToManyField(Tag, verbose_name="Tags") biological_sex = models.CharField(max_length=200, null=True, blank=True) apinatomy_model = models.CharField(max_length=200, null=True, blank=True) @@ -309,7 +305,6 @@ class Meta: ] - class Doi(models.Model): """DOI see https://doi.org/""" @@ -334,7 +329,6 @@ class Note(models.Model): """Note""" note = models.TextField() - tags = models.ManyToManyField(NoteTag, verbose_name="Tags") user = models.ForeignKey(User, verbose_name="User", on_delete=models.DO_NOTHING) provenance = models.ForeignKey( Provenance, diff --git a/backend/composer/serializers.py b/backend/composer/serializers.py index 89cc2ded..049dc850 100644 --- a/backend/composer/serializers.py +++ b/backend/composer/serializers.py @@ -9,7 +9,7 @@ ConnectivityStatement, Doi, Note, - NoteTag, + Tag, Provenance, Specie, Profile, @@ -61,11 +61,11 @@ class Meta: fields = "__all__" -class NoteTagSerializer(serializers.ModelSerializer): +class TagSerializer(serializers.ModelSerializer): """Note Tag""" class Meta: - model = NoteTag + model = Tag fields = "__all__" @@ -133,6 +133,7 @@ class Meta: class ViaViewSerializer(serializers.ModelSerializer): """Via""" + # anatomical_entity = AnatomicalEntitySerializer(read_only=False) class Meta: @@ -143,6 +144,7 @@ class Meta: class ConnectivityStatementSerializer(serializers.ModelSerializer): """Connectivity Statement""" + available_transitions = serializers.SerializerMethodField() path = ViaViewSerializer(source="via_set", many=True, read_only=True) @@ -158,6 +160,7 @@ class Meta: class ConnectivityStatementViewSerializer(ConnectivityStatementSerializer): """Connectivity Statement""" + provenance = ProvenanceSerializer(read_only=True) class Meta(ConnectivityStatementSerializer.Meta): diff --git a/backend/composer/urls.py b/backend/composer/urls.py index 6cc3bae5..c7b4fda9 100644 --- a/backend/composer/urls.py +++ b/backend/composer/urls.py @@ -5,11 +5,12 @@ AnsDivisionViewSet, ConnectivityStatementViewSet, NoteViewSet, - NoteTagViewSet, + TagViewSet, ProvenanceViewSet, SpecieViewSet, ProfileViewSet, - ViaViewSet + TagViewSet, + ViaViewSet, ) # Create a router and register our viewsets with it. @@ -24,11 +25,12 @@ basename="connectivity-statement", ) router.register(r"note", NoteViewSet, basename="note") -router.register(r"note-tag", NoteTagViewSet, basename="note-tag") +router.register(r"note-tag", TagViewSet, basename="note-tag") router.register(r"provenance", ProvenanceViewSet, basename="provenance") router.register(r"specie", SpecieViewSet, basename="specie") router.register(r"profile", ProfileViewSet, basename="profile") -router.register(r'via', ViaViewSet, basename="via") +router.register(r"tag", TagViewSet, basename="tag") +router.register(r"via", ViaViewSet, basename="via") # The API URLs are now determined automatically by the router. urlpatterns = [ diff --git a/backend/composer/views.py b/backend/composer/views.py index 60208f8a..77ba95c4 100644 --- a/backend/composer/views.py +++ b/backend/composer/views.py @@ -8,11 +8,11 @@ AnsDivision, ConnectivityStatement, Note, - NoteTag, + Tag, Provenance, Specie, Profile, - Via + Via, ) from .serializers import ( AnatomicalEntitySerializer, @@ -20,11 +20,11 @@ ConnectivityStatementSerializer, ConnectivityStatementViewSerializer, NoteSerializer, - NoteTagSerializer, + TagSerializer, ProvenanceSerializer, SpecieSerializer, ProfileSerializer, - ViaSerializer + ViaSerializer, ) from .services import ConnectivityStatementService @@ -117,13 +117,13 @@ def transition(self, request, pk=None, transition=None): return Response(self.get_serializer(cs).data) -class NoteTagViewSet(ModelCreateRetrieveViewSet): +class TagViewSet(viewsets.ReadOnlyModelViewSet): """ - NoteTag + Tag """ - queryset = NoteTag.objects.all() - serializer_class = NoteTagSerializer + queryset = Tag.objects.all() + serializer_class = TagSerializer permission_classes = [ permissions.IsAuthenticatedOrReadOnly, ] @@ -172,9 +172,11 @@ def get_queryset(self): return super().get_queryset().filter(user=self.request.user) -class ViaViewSet(mixins.CreateModelMixin, +class ViaViewSet( + mixins.CreateModelMixin, mixins.DestroyModelMixin, - viewsets.GenericViewSet,): + viewsets.GenericViewSet, +): """ Via """