This commit is contained in:
Ross
2021-11-29 19:08:27 +00:00
parent 0344b149a6
commit e6a6fdc6e2
5 changed files with 118 additions and 65 deletions
+13 -5
View File
@@ -1,5 +1,13 @@
from django.contrib import admin from django.contrib import admin
from .models import Case, Series, SeriesImage, Condition, Subspecialty, Finding, SeriesFindings from .models import (
Case,
Series,
SeriesImage,
Condition,
Subspecialty,
Finding,
SeriesFinding,
)
import tagulous.admin import tagulous.admin
@@ -20,7 +28,7 @@ admin.site.register(SeriesImage)
admin.site.register(Condition) admin.site.register(Condition)
admin.site.register(Subspecialty) admin.site.register(Subspecialty)
admin.site.register(Finding) admin.site.register(Finding)
admin.site.register(SeriesFindings) admin.site.register(SeriesFinding)
class AtlasAdminForm(ModelForm): class AtlasAdminForm(ModelForm):
@@ -31,7 +39,7 @@ class AtlasAdminForm(ModelForm):
"description", "description",
"history", "history",
"sign", "sign",
#"findings", # "findings",
"author", "author",
"series", "series",
] ]
@@ -40,8 +48,8 @@ class AtlasAdminForm(ModelForm):
# "normal": RadioSelect( # "normal": RadioSelect(
# choices=[(True, 'Yes'), # choices=[(True, 'Yes'),
# (False, 'No')]) # (False, 'No')])
#"findings": TinyMCE(attrs={"cols": 80, "rows": 30}), # "findings": TinyMCE(attrs={"cols": 80, "rows": 30}),
#"mark_scheme": TinyMCE(attrs={"cols": 80, "rows": 30}), # "mark_scheme": TinyMCE(attrs={"cols": 80, "rows": 30}),
} }
+9 -13
View File
@@ -8,12 +8,7 @@ from django.forms import (
) )
from django.forms import inlineformset_factory from django.forms import inlineformset_factory
from atlas.models import ( from atlas.models import Case, Series, SeriesImage, SeriesFinding
Case,
Series,
SeriesImage,
SeriesFindings
)
from anatomy.models import Modality from anatomy.models import Modality
@@ -33,9 +28,9 @@ class ExaminationForm(ModelForm):
fields = ["examination"] fields = ["examination"]
class SeriesFindingsForm(ModelForm): class SeriesFindingForm(ModelForm):
class Meta: class Meta:
model = SeriesFindings model = SeriesFinding
exclude = ["series", "annotation_json"] exclude = ["series", "annotation_json"]
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
@@ -47,10 +42,11 @@ class SeriesFindingsForm(ModelForm):
# a list of primary key for the selected data. # a list of primary key for the selected data.
initial["series"] = kwargs.pop("series_id") initial["series"] = kwargs.pop("series_id")
super(SeriesFindingsForm, self).__init__(*args, **kwargs) super(SeriesFindingForm, self).__init__(*args, **kwargs)
ModelForm.__init__(self, *args, **kwargs) ModelForm.__init__(self, *args, **kwargs)
class SeriesForm(ModelForm): class SeriesForm(ModelForm):
class Media: class Media:
# Django also includes a few javascript files necessary # Django also includes a few javascript files necessary
@@ -163,9 +159,9 @@ class CaseForm(ModelForm):
"subspecialty", "subspecialty",
"description", "description",
"history", "history",
#"findings", # "findings",
"condition", "condition",
#"sign", # "sign",
"open_access", "open_access",
] ]
# fields = ['question', 'findings', 'subspecialty', 'references'] # fields = ['question', 'findings', 'subspecialty', 'references']
@@ -173,8 +169,8 @@ class CaseForm(ModelForm):
# "normal": RadioSelect( # "normal": RadioSelect(
# choices=[(True, 'Yes'), # choices=[(True, 'Yes'),
# (False, 'No')]) # (False, 'No')])
#"findings": TinyMCE(attrs={"cols": 80, "rows": 20}), # "findings": TinyMCE(attrs={"cols": 80, "rows": 20}),
#"mark_scheme": TinyMCE(attrs={"cols": 80, "rows": 30}), # "mark_scheme": TinyMCE(attrs={"cols": 80, "rows": 30}),
"description": Textarea(attrs={"cols": 80, "rows": 5}), "description": Textarea(attrs={"cols": 80, "rows": 5}),
"history": Textarea(attrs={"cols": 80, "rows": 5}), "history": Textarea(attrs={"cols": 80, "rows": 5}),
} }
+58 -20
View File
@@ -8,42 +8,80 @@ import django.db.models.deletion
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('atlas', '0006_auto_20211128_1448'), ("atlas", "0006_auto_20211128_1448"),
] ]
operations = [ operations = [
migrations.CreateModel( migrations.CreateModel(
name='Finding', name="Finding",
fields=[ fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), (
('name', models.CharField(max_length=255)), "id",
('primary_name', models.BooleanField(default='True')), models.BigAutoField(
('synonym', models.ManyToManyField(blank=True, related_name='_atlas_finding_synonym_+', to='atlas.Finding')), auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("name", models.CharField(max_length=255)),
("primary_name", models.BooleanField(default="True")),
(
"synonym",
models.ManyToManyField(
blank=True,
related_name="_atlas_finding_synonym_+",
to="atlas.Finding",
),
),
], ],
bases=(atlas.models.SynMixin, models.Model), bases=(atlas.models.SynMixin, models.Model),
), ),
migrations.RemoveField( migrations.RemoveField(
model_name='case', model_name="case",
name='findings', name="findings",
), ),
migrations.AlterField( migrations.AlterField(
model_name='case', model_name="case",
name='description', name="description",
field=models.TextField(blank=True, help_text='Description of the case'), field=models.TextField(blank=True, help_text="Description of the case"),
), ),
migrations.AlterField( migrations.AlterField(
model_name='series', model_name="series",
name='description', name="description",
field=models.TextField(blank=True, help_text='Description of stack'), field=models.TextField(blank=True, help_text="Description of stack"),
), ),
migrations.CreateModel( migrations.CreateModel(
name='SeriesFindings', name="SeriesFinding",
fields=[ fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), (
('description', models.TextField(blank=True, help_text='Findings on the series / stack', null=True)), "id",
('annotation_json', models.TextField(blank=True, null=True)), models.BigAutoField(
('findings', models.ManyToManyField(blank=True, to='atlas.Finding')), auto_created=True,
('series', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='findings', to='atlas.series')), primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"description",
models.TextField(
blank=True,
help_text="Findings on the series / stack",
null=True,
),
),
("annotation_json", models.TextField(blank=True, null=True)),
("findings", models.ManyToManyField(blank=True, to="atlas.Finding")),
(
"series",
models.ForeignKey(
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="findings",
to="atlas.series",
),
),
], ],
), ),
] ]
+15 -7
View File
@@ -73,8 +73,9 @@ def findMiddle(input_list):
return input_list[int(middle)] return input_list[int(middle)]
return (input_list[int(middle)], input_list[int(middle - 1)]) return (input_list[int(middle)], input_list[int(middle - 1)])
class SynMixin(object): class SynMixin(object):
#class Meta: # class Meta:
# abstract = True # abstract = True
def __str__(self) -> str: def __str__(self) -> str:
@@ -94,6 +95,7 @@ class Finding(SynMixin, models.Model):
primary_name = models.BooleanField(default="True") primary_name = models.BooleanField(default="True")
class Condition(SynMixin, models.Model): class Condition(SynMixin, models.Model):
name = models.CharField(max_length=255) name = models.CharField(max_length=255)
@@ -103,15 +105,17 @@ class Condition(SynMixin, models.Model):
subspecialty = models.ManyToManyField("subspecialty", blank=True) subspecialty = models.ManyToManyField("subspecialty", blank=True)
class Subspecialty(models.Model): class Subspecialty(models.Model):
name = models.CharField(max_length=255) name = models.CharField(max_length=255)
def __str__(self) -> str: def __str__(self) -> str:
return self.name return self.name
@reversion.register @reversion.register
class Case(models.Model): class Case(models.Model):
#class SubspecialtyChoices(models.TextChoices): # class SubspecialtyChoices(models.TextChoices):
# BREAST = "BR", _("Breast") # BREAST = "BR", _("Breast")
# CARDIAC = "CA", _("Cardiac") # CARDIAC = "CA", _("Cardiac")
# GASTRO = "GI", _("Gastrointestinal and hepatobiliary") # GASTRO = "GI", _("Gastrointestinal and hepatobiliary")
@@ -134,9 +138,9 @@ class Case(models.Model):
history = models.TextField(null=True, blank=True) history = models.TextField(null=True, blank=True)
#findings = models.TextField(null=True, blank=True) # findings = models.TextField(null=True, blank=True)
#subspecialty = models.CharField(max_length=2, choices=SubspecialtyChoices.choices) # subspecialty = models.CharField(max_length=2, choices=SubspecialtyChoices.choices)
subspecialty = models.ManyToManyField(Subspecialty, blank=True) subspecialty = models.ManyToManyField(Subspecialty, blank=True)
condition = models.ManyToManyField(Condition, blank=True) condition = models.ManyToManyField(Condition, blank=True)
@@ -205,18 +209,22 @@ class SeriesImage(models.Model):
info = "File is not a dicom." info = "File is not a dicom."
return info return info
class SeriesFindings(models.Model):
class SeriesFinding(models.Model):
series = models.ForeignKey( series = models.ForeignKey(
"Series", related_name="findings", on_delete=models.SET_NULL, null=True "Series", related_name="findings", on_delete=models.SET_NULL, null=True
) )
description = models.TextField(null=True, blank=True, help_text="Findings on the series / stack") description = models.TextField(
null=True, blank=True, help_text="Findings on the series / stack"
)
findings = models.ManyToManyField(Finding, blank=True) findings = models.ManyToManyField(Finding, blank=True)
annotation_json = models.TextField(null=True, blank=True) annotation_json = models.TextField(null=True, blank=True)
def __str__(self) -> str: def __str__(self) -> str:
return f"{self.series.id}/{self.description}" return f"{self.series.id}/{self.description}"
@reversion.register @reversion.register
class Series(models.Model): class Series(models.Model):
modality = models.ForeignKey( modality = models.ForeignKey(
@@ -259,7 +267,7 @@ class Series(models.Model):
related_name="series", related_name="series",
) )
#findings = models.TextField(null=True, blank=True, help_text="Findings on the series / stack") # findings = models.TextField(null=True, blank=True, help_text="Findings on the series / stack")
open_access = models.BooleanField( open_access = models.BooleanField(
help_text="If a question should be freely available to browse", default=True help_text="If a question should be freely available to browse", default=True
+22 -19
View File
@@ -30,7 +30,7 @@ from .forms import (
SeriesImageFormSet, SeriesImageFormSet,
SeriesFormSet, SeriesFormSet,
ExaminationForm, ExaminationForm,
SeriesFindingsForm SeriesFindingForm,
) )
from .models import ( from .models import (
Case, Case,
@@ -38,8 +38,8 @@ from .models import (
Examination, Examination,
Finding, Finding,
Subspecialty, Subspecialty,
SeriesFindings, SeriesFinding,
SeriesImage SeriesImage,
) )
from .tables import AtlasTable, SeriesTable from .tables import AtlasTable, SeriesTable
from .filters import AtlasFilter, SeriesFilter from .filters import AtlasFilter, SeriesFilter
@@ -117,11 +117,14 @@ def series_detail(request, pk):
# if request.user not in atlas.author.all(): # if request.user not in atlas.author.all():
# raise PermissionDenied # raise PermissionDenied
series_finding_form = SeriesFindingsForm(series_id=series.id) series_finding_form = SeriesFindingForm(series_id=series.id)
# logging.debug(atlas.subspecialty.first().name.all()) # logging.debug(atlas.subspecialty.first().name.all())
return render(request, "atlas/series.html", {"series": series, "series_finding_form": series_finding_form}) return render(
request,
"atlas/series.html",
{"series": series, "series_finding_form": series_finding_form},
)
@login_required @login_required
@@ -516,28 +519,28 @@ class SeriesImagesZipView(SuperuserRequiredMixin, BaseZipView):
return [i.image.file for i in series.images.all()] return [i.image.file for i in series.images.all()]
def create_series_findings(request): def create_series_findings(request):
#posts = Post.objects.all() # posts = Post.objects.all()
response_data = {} response_data = {}
if request.POST.get('action') == 'post': if request.POST.get("action") == "post":
series_id = request.POST.get('series') series_id = request.POST.get("series")
findings_ids = json.loads(request.POST.get('findings')) findings_ids = json.loads(request.POST.get("findings"))
description = request.POST.get('description') description = request.POST.get("description")
annotation_json = json.loads(request.POST.get('annotation_json')) annotation_json = json.loads(request.POST.get("annotation_json"))
series = Series.objects.get(pk=series_id) series = Series.objects.get(pk=series_id)
findings = Finding.objects.filter(pk__in=findings_ids) findings = Finding.objects.filter(pk__in=findings_ids)
sf = SeriesFinding.objects.create(
sf = SeriesFindings.objects.create( series=series,
series = series, description=description,
description = description, annotation_json=annotation_json,
annotation_json = annotation_json,
) )
sf.findings.set(findings) sf.findings.set(findings)
sf.save() sf.save()
return JsonResponse({"success":True}) return JsonResponse({"success": True})
return JsonResponse({"success": False}) return JsonResponse({"success": False})
return render(request, 'create_post.html', {'posts':posts}) return render(request, "create_post.html", {"posts": posts})