migrate examinations to generic model (and start adding mangament)
This commit is contained in:
+1
-2
@@ -6,7 +6,7 @@ from .models import (
|
|||||||
Answer,
|
Answer,
|
||||||
UserAnswer,
|
UserAnswer,
|
||||||
Exam,
|
Exam,
|
||||||
Modality,
|
#Modality,
|
||||||
Region,
|
Region,
|
||||||
BodyPart,
|
BodyPart,
|
||||||
Structure,
|
Structure,
|
||||||
@@ -56,7 +56,6 @@ admin.site.register(AnatomyQuestion, AnatomyAdmin)
|
|||||||
admin.site.register(QuestionType)
|
admin.site.register(QuestionType)
|
||||||
admin.site.register(UserAnswer)
|
admin.site.register(UserAnswer)
|
||||||
admin.site.register(Exam, ExamAdmin)
|
admin.site.register(Exam, ExamAdmin)
|
||||||
admin.site.register(Modality)
|
|
||||||
admin.site.register(Region)
|
admin.site.register(Region)
|
||||||
admin.site.register(BodyPart)
|
admin.site.register(BodyPart)
|
||||||
admin.site.register(Structure)
|
admin.site.register(Structure)
|
||||||
|
|||||||
@@ -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=[],
|
||||||
|
),
|
||||||
|
]
|
||||||
+7
-6
@@ -16,7 +16,7 @@ from sortedm2m.fields import SortedManyToManyField
|
|||||||
|
|
||||||
import string
|
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 collections import defaultdict
|
||||||
from helpers.images import image_as_base64
|
from helpers.images import image_as_base64
|
||||||
@@ -57,11 +57,12 @@ class Region(models.Model):
|
|||||||
return self.region
|
return self.region
|
||||||
|
|
||||||
|
|
||||||
class Modality(models.Model):
|
## TODO: ??? Move to generic app
|
||||||
modality = models.CharField(max_length=200)
|
#class Modality(models.Model):
|
||||||
|
# modality = models.CharField(max_length=200)
|
||||||
def __str__(self):
|
#
|
||||||
return self.modality
|
# def __str__(self):
|
||||||
|
# return self.modality
|
||||||
|
|
||||||
|
|
||||||
class QuestionType(models.Model):
|
class QuestionType(models.Model):
|
||||||
|
|||||||
@@ -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=[],
|
||||||
|
)
|
||||||
|
]
|
||||||
+1
-1
@@ -29,7 +29,6 @@ import string
|
|||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from helpers.images import image_as_base64, pretty_print_dicom
|
from helpers.images import image_as_base64, pretty_print_dicom
|
||||||
|
|
||||||
from anatomy.models import Modality
|
|
||||||
|
|
||||||
from generic.models import (
|
from generic.models import (
|
||||||
CidUser,
|
CidUser,
|
||||||
@@ -44,6 +43,7 @@ from generic.models import (
|
|||||||
QuestionNote,
|
QuestionNote,
|
||||||
SeriesBase,
|
SeriesBase,
|
||||||
SeriesImageBase,
|
SeriesImageBase,
|
||||||
|
Modality,
|
||||||
)
|
)
|
||||||
|
|
||||||
# from generic.models import Examination, Site, Condition, Sign
|
# from generic.models import Examination, Site, Condition, Sign
|
||||||
|
|||||||
@@ -34,8 +34,8 @@
|
|||||||
</a>
|
</a>
|
||||||
<br>
|
<br>
|
||||||
<span class="series-block-popup-link">
|
<span class="series-block-popup-link">
|
||||||
<a href="#"
|
<a href="#"
|
||||||
onclick="return window.create_popup_window('/atlas/series/{{series.pk}}', 'Series')">Popup</a>
|
onclick="return window.create_popup_window('/atlas/series/{{series.pk}}', 'Series')">Popup</a>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
@@ -53,51 +53,53 @@
|
|||||||
<li>{{con.get_link}}</li>
|
<li>{{con.get_link}}</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
<details>
|
<div>
|
||||||
<summary><b>Findings</b></summary>
|
<details>
|
||||||
{% if case.series.all %}
|
<summary><b>Findings</b></summary>
|
||||||
See individual series for more details.<br/>
|
{% if case.series.all %}
|
||||||
{% for series in case.series.all %}
|
{% for series in case.series.all %}
|
||||||
{% for finding in series.findings.all %}
|
{% for finding in series.findings.all %}
|
||||||
<div class="finding-box">
|
<div class="finding-box">
|
||||||
<span>
|
|
||||||
<a href="{{series.get_absolute_url}}">Series {{series.pk}}</a>: {{series.get_examination_full}} |
|
|
||||||
</span>
|
|
||||||
{% if finding.findings.all %}
|
|
||||||
<span>
|
<span>
|
||||||
Findings: {% for f in finding.findings.all %}
|
<a href="{{series.get_absolute_url}}">Series {{series.pk}}</a>: {{series.get_examination_full}} |
|
||||||
{{f.get_link}},
|
|
||||||
{% endfor %}
|
|
||||||
</span>
|
</span>
|
||||||
{% endif %}
|
{% if finding.findings.all %}
|
||||||
{% if finding.structures.all %}
|
<span>
|
||||||
<span>
|
Findings: {% for f in finding.findings.all %}
|
||||||
Structure: {% for s in finding.structures.all %}
|
{{f.get_link}},
|
||||||
{{s.get_link}},
|
{% endfor %}
|
||||||
{% endfor %}
|
</span>
|
||||||
</span>
|
{% endif %}
|
||||||
{% endif %}
|
{% if finding.structures.all %}
|
||||||
{% if finding.description %}
|
<span>
|
||||||
<span>
|
Structure: {% for s in finding.structures.all %}
|
||||||
Description: {{finding.description}}
|
{{s.get_link}},
|
||||||
</span>
|
{% endfor %}
|
||||||
{% endif %}
|
</span>
|
||||||
</div>
|
{% endif %}
|
||||||
|
{% if finding.description %}
|
||||||
|
<span>
|
||||||
|
Description: {{finding.description}}
|
||||||
|
</span>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endfor %}
|
{% else %}
|
||||||
{% else %}
|
No series associated with case.
|
||||||
No findings associated with case.
|
{% endif %}
|
||||||
{% endif %}
|
</details>
|
||||||
</details>
|
</div>
|
||||||
<details open>
|
<div>
|
||||||
<summary><b>Differentials</b></summary>
|
<details open>
|
||||||
<ul>
|
<summary><b>Differentials</b></summary>
|
||||||
{% for diff in case.differentialcase.all %}
|
<ul>
|
||||||
<li>{{diff.condition.get_link}} - {{diff.text}}</li>
|
{% for diff in case.differentialcase.all %}
|
||||||
{% endfor %}
|
<li>{{diff.condition.get_link}} - {{diff.text}}</li>
|
||||||
</ul>
|
{% endfor %}
|
||||||
</details>
|
</ul>
|
||||||
|
</details>
|
||||||
|
</div>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
Subspecialty:
|
Subspecialty:
|
||||||
@@ -114,9 +116,9 @@
|
|||||||
</ul>
|
</ul>
|
||||||
<b>Collections:</b>
|
<b>Collections:</b>
|
||||||
<button
|
<button
|
||||||
hx-get="{% url 'atlas:case_collection_form' case.pk %}"
|
hx-get="{% url 'atlas:case_collection_form' case.pk %}"
|
||||||
hx-target="#collection-form">
|
hx-target="#collection-form">
|
||||||
Add collection</button>
|
Add collection</button>
|
||||||
<div id="collection-form"></div>
|
<div id="collection-form"></div>
|
||||||
<ul>
|
<ul>
|
||||||
{% for collection in case.casecollection_set.all %}
|
{% for collection in case.casecollection_set.all %}
|
||||||
|
|||||||
+2
-1
@@ -6,7 +6,7 @@ from .models import (
|
|||||||
CidUserGroup,
|
CidUserGroup,
|
||||||
Examination,
|
Examination,
|
||||||
#Sign,
|
#Sign,
|
||||||
#Condition,
|
Modality,
|
||||||
Plane,
|
Plane,
|
||||||
Contrast,
|
Contrast,
|
||||||
QuestionNote,
|
QuestionNote,
|
||||||
@@ -35,3 +35,4 @@ admin.site.register(CidUserGroup)
|
|||||||
admin.site.register(UserProfile)
|
admin.site.register(UserProfile)
|
||||||
admin.site.register(UserGrades)
|
admin.site.register(UserGrades)
|
||||||
admin.site.register(Supervisor)
|
admin.site.register(Supervisor)
|
||||||
|
admin.site.register(Modality)
|
||||||
+20
-1
@@ -3,7 +3,7 @@ import django_filters
|
|||||||
|
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
|
|
||||||
from generic.models import CidUser, Supervisor, UserGrades
|
from generic.models import CidUser, Examination, Supervisor, UserGrades
|
||||||
|
|
||||||
|
|
||||||
class CidUserFilter(django_filters.FilterSet):
|
class CidUserFilter(django_filters.FilterSet):
|
||||||
@@ -61,3 +61,22 @@ class UserUserFilter(django_filters.FilterSet):
|
|||||||
# return parent.filter(active=True)
|
# return parent.filter(active=True)
|
||||||
|
|
||||||
return parent
|
return parent
|
||||||
|
|
||||||
|
class ExaminationFilter(django_filters.FilterSet):
|
||||||
|
class Meta:
|
||||||
|
model = Examination
|
||||||
|
fields = {"examination": ["icontains"], "modality": ["exact"]}
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
data=None,
|
||||||
|
queryset=None,
|
||||||
|
prefix=None,
|
||||||
|
strict=None,
|
||||||
|
user=None,
|
||||||
|
request=None,
|
||||||
|
):
|
||||||
|
super(ExaminationFilter, self).__init__(
|
||||||
|
data=data, queryset=queryset, prefix=prefix, request=request
|
||||||
|
)
|
||||||
|
pass
|
||||||
+9
-1
@@ -115,9 +115,17 @@ class ExamAuthorFormMixin(ModelForm):
|
|||||||
|
|
||||||
|
|
||||||
class ExaminationForm(ModelForm):
|
class ExaminationForm(ModelForm):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
# Where is this coming from?
|
||||||
|
if "user" in kwargs:
|
||||||
|
user = kwargs.pop("user")
|
||||||
|
|
||||||
|
ModelForm.__init__(self, *args, **kwargs)
|
||||||
|
super(ExaminationForm, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Examination
|
model = Examination
|
||||||
fields = ["examination"]
|
fields = ["examination", "modality"]
|
||||||
|
|
||||||
|
|
||||||
class QuestionNoteForm(ModelForm):
|
class QuestionNoteForm(ModelForm):
|
||||||
|
|||||||
@@ -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 = [
|
||||||
|
("generic", "0001_initial"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.SeparateDatabaseAndState(
|
||||||
|
state_operations=[
|
||||||
|
migrations.CreateModel(
|
||||||
|
name="Modality",
|
||||||
|
fields=[
|
||||||
|
(
|
||||||
|
"id",
|
||||||
|
models.AutoField(
|
||||||
|
auto_created=True,
|
||||||
|
primary_key=True,
|
||||||
|
serialize=False,
|
||||||
|
verbose_name="ID",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("modality", models.CharField(max_length=200)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
database_operations=[],
|
||||||
|
),
|
||||||
|
migrations.SeparateDatabaseAndState(
|
||||||
|
state_operations=[
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="examination",
|
||||||
|
name="modality",
|
||||||
|
field=models.ForeignKey(
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.SET_NULL,
|
||||||
|
to="generic.modality",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
database_operations=[],
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
# Generated by Django 4.1.4 on 2023-06-19 11:13
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
("generic", "0002_modality_examination_modality"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.SeparateDatabaseAndState(
|
||||||
|
state_operations=[
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name="examination",
|
||||||
|
name="modality",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
database_operations=[],
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
# Generated by Django 4.1.4 on 2023-06-19 11:13
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('generic', '0003_remove_examination_modality'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='examination',
|
||||||
|
name='modality',
|
||||||
|
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='generic.modality'),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
import json
|
import json
|
||||||
|
import os
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||||
from django.db import models
|
from django.db import models
|
||||||
@@ -42,6 +43,11 @@ def findMiddle(input_list):
|
|||||||
else:
|
else:
|
||||||
return input_list[int(middle)]
|
return input_list[int(middle)]
|
||||||
|
|
||||||
|
class Modality(models.Model):
|
||||||
|
modality = models.CharField(max_length=200)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.modality
|
||||||
|
|
||||||
class Plane(models.Model):
|
class Plane(models.Model):
|
||||||
plane = models.CharField(max_length=200, unique=True)
|
plane = models.CharField(max_length=200, unique=True)
|
||||||
@@ -66,6 +72,8 @@ class Contrast(models.Model):
|
|||||||
class Examination(models.Model):
|
class Examination(models.Model):
|
||||||
examination = models.CharField(max_length=200, unique=True)
|
examination = models.CharField(max_length=200, unique=True)
|
||||||
|
|
||||||
|
modality = models.ForeignKey(Modality, on_delete=models.SET_NULL, null=True)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.examination
|
return self.examination
|
||||||
|
|
||||||
|
|||||||
+25
-1
@@ -7,7 +7,7 @@ from easy_thumbnails.files import get_thumbnailer
|
|||||||
|
|
||||||
from easy_thumbnails.exceptions import InvalidImageFormatError
|
from easy_thumbnails.exceptions import InvalidImageFormatError
|
||||||
|
|
||||||
from generic.models import CidUser
|
from generic.models import CidUser, Examination
|
||||||
|
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
|
|
||||||
@@ -259,3 +259,27 @@ class UserUserTable(tables.Table):
|
|||||||
record.username,
|
record.username,
|
||||||
record.email,
|
record.email,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
class ExaminationTable(tables.Table):
|
||||||
|
examination = tables.Column(
|
||||||
|
linkify=("generic:examination_detail", {"pk": tables.A("pk")}),
|
||||||
|
verbose_name="Condition",
|
||||||
|
)
|
||||||
|
|
||||||
|
#edit = tables.LinkColumn(
|
||||||
|
# "generic:examination_update", text="Edit", args=[A("pk")], orderable=False
|
||||||
|
#)
|
||||||
|
delete = tables.LinkColumn(
|
||||||
|
"generic:examination_delete", text="Delete", args=[A("pk")], orderable=False
|
||||||
|
)
|
||||||
|
selection = tables.CheckBoxColumn(accessor="pk", orderable=False)
|
||||||
|
|
||||||
|
# synonym = tables.ManyToManyColumn(verbose_name="Synonyms")
|
||||||
|
#synonym = tables.Column(empty_values=())
|
||||||
|
#parent = tables.ManyToManyColumn(verbose_name="Parents")
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = Examination
|
||||||
|
template_name = "django_tables2/bootstrap4.html"
|
||||||
|
#fields = ("primary", "subspecialty")
|
||||||
|
sequence = ("examination",)
|
||||||
|
|||||||
+44
@@ -0,0 +1,44 @@
|
|||||||
|
{% extends 'generic/base.html' %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="floating-header">
|
||||||
|
<a href="{% url 'generic:examination_update' pk=examination.pk %}" title="Edit the Examination">Edit</a>
|
||||||
|
<a href="{% url 'generic:examination_delete' pk=examination.pk %}" title="Delete the Examination">Delete</a>
|
||||||
|
{% if request.user.is_superuser %}
|
||||||
|
<a href="{% url 'admin:generic_examination_change' examination.id %}"
|
||||||
|
title="Edit the Examination using the admin interface">Admin Edit</a>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h3>Name: {{examination.examination}}</h3>
|
||||||
|
Modality: {{examination.modality}}
|
||||||
|
</div>
|
||||||
|
{% if examination.atlas_series_examination_set.all %}
|
||||||
|
<h4>Associated Atlas Cases</h4>
|
||||||
|
<ul>
|
||||||
|
|
||||||
|
{% for case in examination.atlas_series_examination_set.all %}
|
||||||
|
<li>{{case}}</li>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
{% endif %}
|
||||||
|
{% if examination.longs_series_examination_set.all %}
|
||||||
|
<h4>Associated Longs Cases</h4>
|
||||||
|
<ul>
|
||||||
|
|
||||||
|
{% for case in examination.longs_series_examination_set.all %}
|
||||||
|
<li>{{case}}</li>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block js %}
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
{% extends "atlas/base.html" %}
|
||||||
|
<!-- {% load static from static %} -->
|
||||||
|
|
||||||
|
{% block css %}
|
||||||
|
{% endblock %}
|
||||||
|
{% block js %}
|
||||||
|
<!--<script type="text/javascript" src="/admin/jsi18n/"></script>-->
|
||||||
|
{{form.media}}
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- {{ form.media }} -->
|
||||||
|
{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
<h2>Add/Edit Examination</h2>
|
||||||
|
Use this form to create or edit a examination.
|
||||||
|
<form action="" method="post" enctype="multipart/form-data" id="examination-form">
|
||||||
|
{% csrf_token %}
|
||||||
|
|
||||||
|
<table>
|
||||||
|
{{ form.as_table }}
|
||||||
|
</table>
|
||||||
|
<input type="submit" class="submit-button" value="Submit" name="submit">
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
||||||
@@ -9,6 +9,10 @@ app_name = "generic"
|
|||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
# path('', views.question_list, name='question_list'),
|
# path('', views.question_list, name='question_list'),
|
||||||
|
path("examination/", views.ExaminationView.as_view(), name="examination_view"),
|
||||||
|
path("examination/<int:pk>", views.examination_detail, name="examination_detail"),
|
||||||
|
path("examination/<int:pk>/delete", views.ExaminationDelete.as_view(), name="examination_delete"),
|
||||||
|
path("examination/<int:pk>/update", views.ExaminationUpdate.as_view(), name="examination_update"),
|
||||||
path("examination/create/", views.create_examination, name="create_examination"),
|
path("examination/create/", views.create_examination, name="create_examination"),
|
||||||
path(
|
path(
|
||||||
"examination/ajax/get_examination_id",
|
"examination/ajax/get_examination_id",
|
||||||
|
|||||||
+36
-2
@@ -44,9 +44,10 @@ from django_tables2.views import SingleTableMixin
|
|||||||
from reversion.views import RevisionMixin
|
from reversion.views import RevisionMixin
|
||||||
from atlas.models import CaseCollection
|
from atlas.models import CaseCollection
|
||||||
from generic.decorators import user_is_cid_user_manager
|
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 (
|
from .forms import (
|
||||||
CidUserForm,
|
CidUserForm,
|
||||||
@@ -177,6 +178,21 @@ def create_examination(request):
|
|||||||
request, "rapids/create_simple.html", {"form": form, "name": "Examination"}
|
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
|
@csrf_exempt
|
||||||
def get_examination_id(request):
|
def get_examination_id(request):
|
||||||
@@ -2954,3 +2970,21 @@ class SupervisorCreate(CidManagerRequiredMixin, CreateView):
|
|||||||
|
|
||||||
class SupervisorList(CidManagerRequiredMixin, ListView):
|
class SupervisorList(CidManagerRequiredMixin, ListView):
|
||||||
model = Supervisor
|
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
|
||||||
@@ -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=[],
|
||||||
|
)
|
||||||
|
]
|
||||||
+1
-2
@@ -25,8 +25,6 @@ import string
|
|||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from helpers.images import image_as_base64, pretty_print_dicom
|
from helpers.images import image_as_base64, pretty_print_dicom
|
||||||
|
|
||||||
from anatomy.models import Modality
|
|
||||||
|
|
||||||
from generic.models import (
|
from generic.models import (
|
||||||
CidUser,
|
CidUser,
|
||||||
CidUserGroup,
|
CidUserGroup,
|
||||||
@@ -41,6 +39,7 @@ from generic.models import (
|
|||||||
SeriesImageBase,
|
SeriesImageBase,
|
||||||
UserAnswerBase,
|
UserAnswerBase,
|
||||||
UserUserGroup,
|
UserUserGroup,
|
||||||
|
Modality
|
||||||
)
|
)
|
||||||
|
|
||||||
# from generic.models import Examination, Site, Condition, Sign
|
# from generic.models import Examination, Site, Condition, Sign
|
||||||
|
|||||||
@@ -31,6 +31,10 @@
|
|||||||
<div>
|
<div>
|
||||||
{% if request.user.is_staff %}
|
{% if request.user.is_staff %}
|
||||||
Manage users <a href="{% url 'accounts_list'%}">here</a> and candidates <a href="{% url 'generic:manage_cids'%}">here</a>
|
Manage users <a href="{% url 'accounts_list'%}">here</a> and candidates <a href="{% url 'generic:manage_cids'%}">here</a>
|
||||||
|
|
||||||
|
<p>Manage <a href="{% url 'generic:examination_view' %}">Examinations</a>
|
||||||
|
|
||||||
|
</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
Reference in New Issue
Block a user