From d30857bb2c54e7ce7e3b141aa0a4d7d3fd6f6980 Mon Sep 17 00:00:00 2001 From: Ross Date: Fri, 1 Apr 2022 18:49:58 +0100 Subject: [PATCH] . --- atlas/migrations/0032_auto_20220401_1849.py | 38 ++++++++++ atlas/models.py | 80 +++++++++++++++++---- generic/models.py | 3 +- 3 files changed, 107 insertions(+), 14 deletions(-) create mode 100644 atlas/migrations/0032_auto_20220401_1849.py diff --git a/atlas/migrations/0032_auto_20220401_1849.py b/atlas/migrations/0032_auto_20220401_1849.py new file mode 100644 index 00000000..afb5337d --- /dev/null +++ b/atlas/migrations/0032_auto_20220401_1849.py @@ -0,0 +1,38 @@ +# Generated by Django 3.2.10 on 2022-04-01 17:49 + +import django.core.validators +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('generic', '0026_ciduser_generic_cid_cid_291418_idx'), + ('atlas', '0031_alter_casecollection_collection_type'), + ] + + operations = [ + migrations.AddField( + model_name='casecollection', + name='valid_users', + field=models.ManyToManyField(blank=True, related_name='casecollection_exams', to='generic.CidUser'), + ), + migrations.AlterField( + model_name='casecollection', + name='collection_type', + field=models.CharField(choices=[('REV', 'Review'), ('REP', 'Report')], default='REP', max_length=3), + ), + migrations.CreateModel( + name='CidReportAnswer', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('answer', models.TextField(blank=True)), + ('cid', models.BigIntegerField(help_text='Candidate ID')), + ('created', models.DateTimeField(auto_now_add=True)), + ('updated', models.DateTimeField(auto_now=True)), + ('score', models.IntegerField(blank=True, null=True, validators=[django.core.validators.MaxValueValidator(10), django.core.validators.MinValueValidator(0)])), + ('question', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='atlas.casedetail')), + ], + ), + ] diff --git a/atlas/models.py b/atlas/models.py index 5abeff1d..b3c36e01 100644 --- a/atlas/models.py +++ b/atlas/models.py @@ -29,6 +29,7 @@ from helpers.images import image_as_base64, pretty_print_dicom from anatomy.models import Modality from generic.models import ( + CidUser, Examination, # Condition, ExamBase, @@ -51,6 +52,8 @@ import reversion from django.contrib.contenttypes.fields import GenericRelation +from django.core.validators import MaxValueValidator, MinValueValidator + image_storage = FileSystemStorage( # Physical file location ROOT @@ -72,6 +75,7 @@ def findMiddle(input_list): return input_list[int(middle)] return (input_list[int(middle)], input_list[int(middle - 1)]) + class SynMixin(object): # class Meta: # abstract = True @@ -274,7 +278,13 @@ class Case(models.Model): notes = GenericRelation(QuestionNote) - previous_case = models.OneToOneField("Case", on_delete=models.SET_NULL, null=True, related_name="next_case", blank=True) + previous_case = models.OneToOneField( + "Case", + on_delete=models.SET_NULL, + null=True, + related_name="next_case", + blank=True, + ) # question_file = models.FileField(upload_to=question_file_directory_path, blank=True, null=True) @@ -301,9 +311,8 @@ class Case(models.Model): html = "" for s in self.series.all(): html += s.get_block() - - return html + return html def get_long_str(self): examinations = [series.get_examination() for series in self.series.all()] @@ -401,7 +410,6 @@ class Series(models.Model): def __str__(self): return f"{self.pk}:{self.description}" - def get_full_str(self): if self.case: case_id = ", ".format([case.pk for case in self.case.all()]) @@ -568,23 +576,45 @@ class CaseCollection(models.Model): help_text="If a collection should published", default=True ) - show_title = models.BooleanField(default=False, help_text="Show the title of the cases") - show_description = models.BooleanField(default=False, help_text="Show the description of the cases") - show_discussion = models.BooleanField(default=False, help_text="Show the case discussion") + show_title = models.BooleanField( + default=False, help_text="Show the title of the cases" + ) + show_description = models.BooleanField( + default=False, help_text="Show the description of the cases" + ) + show_discussion = models.BooleanField( + default=False, help_text="Show the case discussion" + ) show_report = models.BooleanField(default=False, help_text="Show the case report") author = models.ManyToManyField( settings.AUTH_USER_MODEL, blank=True, help_text="Author of the collection", - #related_name="atlas_authored_cases", + # related_name="atlas_authored_cases", + ) + + cid_users = GenericRelation("generic.CidUserExam") + + valid_users = models.ManyToManyField( + CidUser, blank=True, related_name="casecollection_exams" ) class COLLECTION_TYPE_CHOICES(models.TextChoices): - REVIEW = "RE", _("Review"), - BASIC_TEXT_INPUT = "BTI", _("Basic Text Input"), + REVIEW = ( + "REV", + _("Review"), + ) + REPORT = ( + "REP", + _("Report"), + ) - collection_type = models.CharField(max_length=3, choices=COLLECTION_TYPE_CHOICES.choices, default=COLLECTION_TYPE_CHOICES.REVIEW) + collection_type = models.CharField( + max_length=3, + choices=COLLECTION_TYPE_CHOICES.choices, + default=COLLECTION_TYPE_CHOICES.REPORT, + ) def get_absolute_url(self): return reverse("atlas:collection_detail_view", kwargs={"pk": self.pk}) @@ -597,7 +627,7 @@ class CaseCollection(models.Model): authors = [i for i in self.author.all()] return authors - + class CaseDetail(models.Model): case = models.ForeignKey(Case, on_delete=models.CASCADE) collection = models.ForeignKey(CaseCollection, on_delete=models.CASCADE) @@ -606,3 +636,29 @@ class CaseDetail(models.Model): class Meta: ordering = ("sort_order",) + + +class CidReportAnswer(models.Model): + question = models.ForeignKey(CaseDetail, on_delete=models.CASCADE ) + + answer = models.TextField(blank=True) + + cid = models.BigIntegerField( + blank=False, + help_text="Candidate ID", + ) + + created = models.DateTimeField(auto_now_add=True) + updated = models.DateTimeField(auto_now=True) + + score = models.IntegerField( + blank=True, null=True, validators=[MaxValueValidator(10), MinValueValidator(0)] + ) + + def save(self, *args, **kwargs): + self.clean() + return super(CidReportAnswer, self).save(*args, **kwargs) + + def clean(self): + if self.answer: + self.answer = self.answer.strip() diff --git a/generic/models.py b/generic/models.py index 0b69454a..8d51b95f 100644 --- a/generic/models.py +++ b/generic/models.py @@ -118,7 +118,7 @@ class ExamBase(models.Model): user_scores = models.JSONField(default=dict) - notes = GenericRelation("generic.CidUserExam") + cid_users = GenericRelation("generic.CidUserExam") # time_limit = models.IntegerField( # help_text="Exam time limit (in seconds). Default is 2100 secondse (35 minutes)", @@ -186,7 +186,6 @@ class ExamBase(models.Model): c = CidUserExam.objects.filter( content_type=content_type, object_id=self.pk, cid_user=cid_user ).first() - print(c) if c: return c