From 6c1fd3ae2f249f54c809784a0040d6cfdc42ce98 Mon Sep 17 00:00:00 2001
From: Ross
Date: Mon, 19 Jun 2023 12:37:55 +0100
Subject: [PATCH] migrate examinations to generic model (and start adding
mangament)
---
anatomy/admin.py | 3 +-
...natomyquestion_modality_delete_modality.py | 47 +++++++++
anatomy/models.py | 13 +--
.../migrations/0003_alter_series_modality.py | 29 ++++++
atlas/models.py | 2 +-
atlas/templates/atlas/case_display_block.html | 96 ++++++++++---------
generic/admin.py | 3 +-
generic/filters.py | 21 +++-
generic/forms.py | 10 +-
.../0002_modality_examination_modality.py | 47 +++++++++
.../0003_remove_examination_modality.py | 21 ++++
.../migrations/0004_examination_modality.py | 19 ++++
generic/models.py | 8 ++
generic/tables.py | 26 ++++-
.../templates/generic/examination_detail.html | 44 +++++++++
.../templates/generic/examination_form.html | 26 +++++
generic/urls.py | 4 +
generic/views.py | 38 +++++++-
.../0002_alter_longseries_modality.py | 29 ++++++
longs/models.py | 3 +-
templates/index.html | 4 +
21 files changed, 429 insertions(+), 64 deletions(-)
create mode 100644 anatomy/migrations/0003_alter_anatomyquestion_modality_delete_modality.py
create mode 100644 atlas/migrations/0003_alter_series_modality.py
create mode 100644 generic/migrations/0002_modality_examination_modality.py
create mode 100644 generic/migrations/0003_remove_examination_modality.py
create mode 100644 generic/migrations/0004_examination_modality.py
create mode 100755 generic/templates/generic/examination_detail.html
create mode 100755 generic/templates/generic/examination_form.html
create mode 100644 longs/migrations/0002_alter_longseries_modality.py
diff --git a/anatomy/admin.py b/anatomy/admin.py
index 2ba4072e..23344123 100644
--- a/anatomy/admin.py
+++ b/anatomy/admin.py
@@ -6,7 +6,7 @@ from .models import (
Answer,
UserAnswer,
Exam,
- Modality,
+ #Modality,
Region,
BodyPart,
Structure,
@@ -56,7 +56,6 @@ admin.site.register(AnatomyQuestion, AnatomyAdmin)
admin.site.register(QuestionType)
admin.site.register(UserAnswer)
admin.site.register(Exam, ExamAdmin)
-admin.site.register(Modality)
admin.site.register(Region)
admin.site.register(BodyPart)
admin.site.register(Structure)
diff --git a/anatomy/migrations/0003_alter_anatomyquestion_modality_delete_modality.py b/anatomy/migrations/0003_alter_anatomyquestion_modality_delete_modality.py
new file mode 100644
index 00000000..a67d689a
--- /dev/null
+++ b/anatomy/migrations/0003_alter_anatomyquestion_modality_delete_modality.py
@@ -0,0 +1,47 @@
+# Generated by Django 4.1.4 on 2023-06-19 10:51
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+ dependencies = [
+ ("longs", "0002_alter_longseries_modality"),
+ ("atlas", "0003_alter_series_modality"),
+ ("generic", "0002_modality_examination_modality"),
+ ("anatomy", "0002_initial"),
+ ]
+
+ operations = [
+ # migrations.DeleteModel(
+ # name='Modality',
+ # ),
+ migrations.SeparateDatabaseAndState(
+ state_operations=[
+ migrations.DeleteModel(
+ name="Modality",
+ ),
+ ],
+ database_operations=[
+ migrations.AlterModelTable(
+ name="Modality",
+ table="generic_modality",
+ ),
+ ],
+ ),
+ migrations.SeparateDatabaseAndState(
+ state_operations=[
+ migrations.AlterField(
+ model_name="anatomyquestion",
+ name="modality",
+ field=models.ForeignKey(
+ help_text="Modality of the image",
+ null=True,
+ on_delete=django.db.models.deletion.SET_NULL,
+ to="generic.modality",
+ ),
+ ),
+ ],
+ database_operations=[],
+ ),
+ ]
diff --git a/anatomy/models.py b/anatomy/models.py
index 25bb1af6..40f99091 100644
--- a/anatomy/models.py
+++ b/anatomy/models.py
@@ -16,7 +16,7 @@ from sortedm2m.fields import SortedManyToManyField
import string
-from generic.models import CidUser, CidUserGroup, ExamUserStatus, Examination, ExamBase, QuestionBase, QuestionNote, UserAnswerBase, UserUserGroup
+from generic.models import CidUser, CidUserGroup, ExamUserStatus, Examination, ExamBase, QuestionBase, QuestionNote, UserAnswerBase, UserUserGroup, Modality
from collections import defaultdict
from helpers.images import image_as_base64
@@ -57,11 +57,12 @@ class Region(models.Model):
return self.region
-class Modality(models.Model):
- modality = models.CharField(max_length=200)
-
- def __str__(self):
- return self.modality
+## TODO: ??? Move to generic app
+#class Modality(models.Model):
+# modality = models.CharField(max_length=200)
+#
+# def __str__(self):
+# return self.modality
class QuestionType(models.Model):
diff --git a/atlas/migrations/0003_alter_series_modality.py b/atlas/migrations/0003_alter_series_modality.py
new file mode 100644
index 00000000..e93d4bf8
--- /dev/null
+++ b/atlas/migrations/0003_alter_series_modality.py
@@ -0,0 +1,29 @@
+# Generated by Django 4.1.4 on 2023-06-19 10:51
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+ dependencies = [
+ ("generic", "0002_modality_examination_modality"),
+ ("atlas", "0002_initial"),
+ ]
+
+ operations = [
+ migrations.SeparateDatabaseAndState(
+ state_operations=[
+ migrations.AlterField(
+ model_name="series",
+ name="modality",
+ field=models.ForeignKey(
+ null=True,
+ on_delete=django.db.models.deletion.SET_NULL,
+ related_name="atlas_series_modality",
+ to="generic.modality",
+ ),
+ ),
+ ],
+ database_operations=[],
+ )
+ ]
diff --git a/atlas/models.py b/atlas/models.py
index 3c0b146c..84689252 100644
--- a/atlas/models.py
+++ b/atlas/models.py
@@ -29,7 +29,6 @@ import string
from collections import defaultdict
from helpers.images import image_as_base64, pretty_print_dicom
-from anatomy.models import Modality
from generic.models import (
CidUser,
@@ -44,6 +43,7 @@ from generic.models import (
QuestionNote,
SeriesBase,
SeriesImageBase,
+ Modality,
)
# from generic.models import Examination, Site, Condition, Sign
diff --git a/atlas/templates/atlas/case_display_block.html b/atlas/templates/atlas/case_display_block.html
index 5f009bfe..60c3454b 100755
--- a/atlas/templates/atlas/case_display_block.html
+++ b/atlas/templates/atlas/case_display_block.html
@@ -34,8 +34,8 @@
@@ -53,51 +53,53 @@
{{con.get_link}}
{% endfor %}
-
- Findings
- {% if case.series.all %}
- See individual series for more details.
- {% for series in case.series.all %}
- {% for finding in series.findings.all %}
-
-
- Series {{series.pk}} : {{series.get_examination_full}} |
-
- {% if finding.findings.all %}
+
+
+ Findings
+ {% if case.series.all %}
+ {% for series in case.series.all %}
+ {% for finding in series.findings.all %}
+
- Findings: {% for f in finding.findings.all %}
- {{f.get_link}},
- {% endfor %}
+ Series {{series.pk}} : {{series.get_examination_full}} |
- {% endif %}
- {% if finding.structures.all %}
-
- Structure: {% for s in finding.structures.all %}
- {{s.get_link}},
- {% endfor %}
-
- {% endif %}
- {% if finding.description %}
-
- Description: {{finding.description}}
-
- {% endif %}
-
-
+ {% if finding.findings.all %}
+
+ Findings: {% for f in finding.findings.all %}
+ {{f.get_link}},
+ {% endfor %}
+
+ {% endif %}
+ {% if finding.structures.all %}
+
+ Structure: {% for s in finding.structures.all %}
+ {{s.get_link}},
+ {% endfor %}
+
+ {% endif %}
+ {% if finding.description %}
+
+ Description: {{finding.description}}
+
+ {% endif %}
+
+ {% endfor %}
{% endfor %}
- {% endfor %}
- {% else %}
- No findings associated with case.
- {% endif %}
-
-
- Differentials
-
- {% for diff in case.differentialcase.all %}
- {{diff.condition.get_link}} - {{diff.text}}
- {% endfor %}
-
-
+ {% else %}
+ No series associated with case.
+ {% endif %}
+
+
+
+
+ Differentials
+
+ {% for diff in case.differentialcase.all %}
+ {{diff.condition.get_link}} - {{diff.text}}
+ {% endfor %}
+
+
+
Subspecialty:
@@ -114,9 +116,9 @@
Collections:
- Add collection
+ hx-get="{% url 'atlas:case_collection_form' case.pk %}"
+ hx-target="#collection-form">
+ Add collection
+{% endblock %}
diff --git a/generic/urls.py b/generic/urls.py
index ebaed53c..ddde4b7b 100755
--- a/generic/urls.py
+++ b/generic/urls.py
@@ -9,6 +9,10 @@ app_name = "generic"
urlpatterns = [
# path('', views.question_list, name='question_list'),
+ path("examination/", views.ExaminationView.as_view(), name="examination_view"),
+ path("examination/", views.examination_detail, name="examination_detail"),
+ path("examination//delete", views.ExaminationDelete.as_view(), name="examination_delete"),
+ path("examination//update", views.ExaminationUpdate.as_view(), name="examination_update"),
path("examination/create/", views.create_examination, name="create_examination"),
path(
"examination/ajax/get_examination_id",
diff --git a/generic/views.py b/generic/views.py
index 6e23ffd8..1da5b42b 100644
--- a/generic/views.py
+++ b/generic/views.py
@@ -44,9 +44,10 @@ from django_tables2.views import SingleTableMixin
from reversion.views import RevisionMixin
from atlas.models import CaseCollection
from generic.decorators import user_is_cid_user_manager
-from generic.filters import CidUserFilter
+from generic.filters import CidUserFilter, ExaminationFilter
-from generic.tables import CidUserExamTable, CidUserTable
+from generic.tables import CidUserExamTable, CidUserTable, ExaminationTable
+from generic.mixins import SuperuserRequiredMixin
from .forms import (
CidUserForm,
@@ -177,6 +178,21 @@ def create_examination(request):
request, "rapids/create_simple.html", {"form": form, "name": "Examination"}
)
+@login_required
+@user_passes_test(lambda u: u.is_superuser)
+def examination_detail(request, pk):
+ examination = get_object_or_404(Examination, pk=pk)
+
+ # logging.debug(atlas.subspecialty.first().name.all())
+ return render(
+ request,
+ "generic/examination_detail.html",
+ {
+ "examination": examination,
+ },
+ )
+
+
@csrf_exempt
def get_examination_id(request):
@@ -2954,3 +2970,21 @@ class SupervisorCreate(CidManagerRequiredMixin, CreateView):
class SupervisorList(CidManagerRequiredMixin, ListView):
model = Supervisor
+
+class ExaminationView(SuperuserRequiredMixin, SingleTableMixin, FilterView):
+ model = Examination
+ table_class = ExaminationTable
+ template_name = "atlas/view.html"
+
+ filterset_class = ExaminationFilter
+
+
+class ExaminationDelete(RevisionMixin, SuperuserRequiredMixin, DeleteView):
+ model = Examination
+ template_name = "confirm_delete.html"
+ success_url = reverse_lazy("generic:examination_view")
+
+
+class ExaminationUpdate(UpdateView, SuperuserRequiredMixin):
+ model = Examination
+ form_class = ExaminationForm
\ No newline at end of file
diff --git a/longs/migrations/0002_alter_longseries_modality.py b/longs/migrations/0002_alter_longseries_modality.py
new file mode 100644
index 00000000..804c8313
--- /dev/null
+++ b/longs/migrations/0002_alter_longseries_modality.py
@@ -0,0 +1,29 @@
+# Generated by Django 4.1.4 on 2023-06-19 10:51
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+ dependencies = [
+ ("generic", "0002_modality_examination_modality"),
+ ("longs", "0001_initial"),
+ ]
+
+ operations = [
+ migrations.SeparateDatabaseAndState(
+ state_operations=[
+ migrations.AlterField(
+ model_name="longseries",
+ name="modality",
+ field=models.ForeignKey(
+ null=True,
+ on_delete=django.db.models.deletion.SET_NULL,
+ related_name="series_modality",
+ to="generic.modality",
+ ),
+ ),
+ ],
+ database_operations=[],
+ )
+ ]
diff --git a/longs/models.py b/longs/models.py
index eb5b25df..2378f0bd 100644
--- a/longs/models.py
+++ b/longs/models.py
@@ -25,8 +25,6 @@ import string
from collections import defaultdict
from helpers.images import image_as_base64, pretty_print_dicom
-from anatomy.models import Modality
-
from generic.models import (
CidUser,
CidUserGroup,
@@ -41,6 +39,7 @@ from generic.models import (
SeriesImageBase,
UserAnswerBase,
UserUserGroup,
+ Modality
)
# from generic.models import Examination, Site, Condition, Sign
diff --git a/templates/index.html b/templates/index.html
index 426c0bce..f9866a42 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -31,6 +31,10 @@
{% if request.user.is_staff %}
Manage users
here and candidates
here
+
+
Manage Examinations
+
+
{% endif %}
{% endblock %}