This commit is contained in:
Ross
2021-02-06 14:33:33 +00:00
parent d4b0ad6985
commit 666ec9013a
12 changed files with 205 additions and 80 deletions
+114 -64
View File
@@ -22,9 +22,11 @@ import string
from anatomy.models import Modality
from generic.models import Examination, Condition, Sign
#from generic.models import Examination, Site, Condition, Sign
# from generic.models import Examination, Site, Condition, Sign
from easy_thumbnails.files import get_thumbnailer
from easy_thumbnails.exceptions import InvalidImageFormatError
image_storage = FileSystemStorage(
# Physical file location ROOT
@@ -33,21 +35,23 @@ image_storage = FileSystemStorage(
base_url=u"{0}longs/".format(settings.MEDIA_URL),
)
def image_directory_path(instance, filename):
return u"picture/{0}".format(filename)
def findMiddle(input_list):
middle = float(len(input_list))/2
middle = float(len(input_list)) / 2
if middle % 2 != 0:
return input_list[int(middle - .5)]
return input_list[int(middle - 0.5)]
else:
return (input_list[int(middle)])
return (input_list[int(middle)], input_list[int(middle-1)])
return input_list[int(middle)]
return (input_list[int(middle)], input_list[int(middle - 1)])
class Long(models.Model):
#author = models.ForeignKey('auth.User', on_delete=models.CASCADE)
#image = models.ImageField()
# author = models.ForeignKey('auth.User', on_delete=models.CASCADE)
# image = models.ImageField()
history = models.TextField(null=True, blank=True)
feedback = models.TextField(null=True, blank=True)
@@ -55,12 +59,12 @@ class Long(models.Model):
condition = tagulous.models.TagField(
to=Condition,
blank=True,
help_text=
"Associated condition. Will allow searching / filtering and tips / hints to be displayed. Conditions with spaces must be enclosed in quotes \"...\""
help_text='Associated condition. Will allow searching / filtering and tips / hints to be displayed. Conditions with spaces must be enclosed in quotes "..."',
)
sign = tagulous.models.TagField(
to=Sign, blank=True, help_text='Radiological signs in the question')
to=Sign, blank=True, help_text="Radiological signs in the question"
)
# Model answers
model_observations = models.TextField(null=True, blank=True)
@@ -69,9 +73,8 @@ class Long(models.Model):
model_differential_diagnosis = models.TextField(null=True, blank=True)
model_management = models.TextField(null=True, blank=True)
DEFAULT_SITE_ID = 1
#site = models.ManyToManyField(
# site = models.ManyToManyField(
# Site,
# blank=True,
# default=DEFAULT_SITE_ID,
@@ -80,22 +83,23 @@ class Long(models.Model):
verified = models.BooleanField(default=False)
created_date = models.DateTimeField(default=timezone.now)
published_date = models.DateTimeField(blank=True, null=True)
author = models.ManyToManyField(settings.AUTH_USER_MODEL,
blank=True,
help_text='Author of question',
related_name="long_authored_questions")
scrapped = models.BooleanField(
default=False,
help_text='Question has been scrapped and will not be shown')
open_access = models.BooleanField(
help_text="If an question should be freely available to browse", default=True
author = models.ManyToManyField(
settings.AUTH_USER_MODEL,
blank=True,
help_text="Author of question",
related_name="long_authored_questions",
)
scrapped = models.BooleanField(
default=False, help_text="Question has been scrapped and will not be shown"
)
open_access = models.BooleanField(
help_text="If a question should be freely available to browse", default=True
)
def get_absolute_url(self):
return reverse('longs:long_detail', kwargs={'pk': self.pk})
return reverse("longs:long_detail", kwargs={"pk": self.pk})
def get_authors(self):
"""Returns a comma seperated text list of authors"""
@@ -116,7 +120,6 @@ class Long(models.Model):
exams = ", ".join(e)
return exams
def GetImages(self, feedback=False):
qs = self.images.all()
@@ -128,28 +131,64 @@ class Long(models.Model):
return images
def GetImageUrls(self):
return ",".join(["http://penracourses.org.uk{}".format(i.url) for i in self.GetImages()])
#def GetNonFeedbackQuestionImages(self):
#return self.GetImages()
return ",".join(
["http://penracourses.org.uk{}".format(i.url) for i in self.GetImages()]
)
# def GetNonFeedbackQuestionImages(self):
# return self.GetImages()
class LongSeriesImage(models.Model):
image = models.ImageField(upload_to=image_directory_path, storage=image_storage)
position = models.IntegerField(default=0)
series = models.ForeignKey("LongSeries", related_name="images", on_delete=models.SET_NULL, null=True)
series = models.ForeignKey(
"LongSeries", related_name="images", on_delete=models.SET_NULL, null=True
)
class LongSeries(models.Model):
modality = models.ForeignKey(Modality, related_name="series_modality", on_delete=models.SET_NULL, null=True)
modality = models.ForeignKey(
Modality, related_name="series_modality", on_delete=models.SET_NULL, null=True
)
examination = models.ForeignKey(
Examination, help_text="Name of the examination", related_name="series_examination", on_delete=models.SET_NULL, null=True)
long = models.ForeignKey("Long", help_text="The question this series should be associated with", related_name="series", on_delete=models.SET_NULL, null=True)
description = models.TextField(blank=True, help_text="Description of stack, for admin organisation, will not be visible when taking")
Examination,
help_text="Name of the examination",
related_name="series_examination",
on_delete=models.SET_NULL,
null=True,
)
long = models.ForeignKey(
"Long",
help_text="The question this series should be associated with",
related_name="series",
on_delete=models.SET_NULL,
null=True,
)
description = models.TextField(
blank=True,
help_text="Description of stack, for admin organisation, will not be visible when taking",
)
author = models.ForeignKey(
settings.AUTH_USER_MODEL,
blank=True,
null=True,
related_name="long_series",
on_delete=models.CASCADE,
)
def __str__(self):
return "{} : {} [{}]".format(self.get_examination(), self.description, self.long.pk)
return "{} : {} [{}]".format(
self.get_examination(), self.description, self.long.pk
)
def get_author_objects(self):
"""Returns a comma seperated text list of authors"""
if self.author:
return self.author.all()
else:
return ["None"]
if self.long:
authors = [i for i in self.long.author.all()]
else:
@@ -157,15 +196,21 @@ class LongSeries(models.Model):
return authors
def get_author_display(self):
return ", ".join(self.get_author_objects())
def get_examination(self):
"""Returns a comma seperated text list of regions"""
return str(self.examination)
def get_absolute_url(self):
return reverse('longs:long_series_detail', kwargs={'pk': self.pk})
return reverse("longs:long_series_detail", kwargs={"pk": self.pk})
def get_image_urls(self, feedback=False):
images = ["http://penracourses.org.uk{}".format(i.image.url) for i in self.images.all()]
images = [
"http://penracourses.org.uk{}".format(i.image.url)
for i in self.images.all()
]
return ",".join(images)
@@ -173,21 +218,25 @@ class LongSeries(models.Model):
images = self.images.all()
if len(images) < 1:
return 'No images', 0
return "No images", 0
img = findMiddle(images).image
thumbnailer = get_thumbnailer(img)
try:
thumbnailer = get_thumbnailer(img)
except InvalidImageFormatError:
return format_html('<span title="{}">Invalid image url<span>', image_object)
thumbnail = thumbnailer["exam-list"]
return '<img src="/media/{}" />'.format(thumbnail), len(images)
def get_block(self):
examination = self.get_examination()
thumb, image_number = self.get_thumbnail()
return format_html('<div>{}<br/>{}<br/>Images: {}</div>', examination, thumb, image_number )
return format_html(
"<div>{}<br/>{}<br/>Images: {}</div>", examination, thumb, image_number
)
#class LongImage(models.Model):
# class LongImage(models.Model):
# long = models.ForeignKey(Long,
# related_name="images",
# on_delete=models.CASCADE)
@@ -207,47 +256,43 @@ class LongSeries(models.Model):
class Note(models.Model):
long = models.ForeignKey(Long,
related_name="long_notes",
on_delete=models.CASCADE,
null=True)
#author = models.ForeignKey(User,
author = models.ForeignKey( settings.AUTH_USER_MODEL,
related_name="long_notes",
on_delete=models.CASCADE)
long = models.ForeignKey(
Long, related_name="long_notes", on_delete=models.CASCADE, null=True
)
# author = models.ForeignKey(User,
author = models.ForeignKey(
settings.AUTH_USER_MODEL, related_name="long_notes", on_delete=models.CASCADE
)
note = models.TextField()
created_on = models.DateTimeField(auto_now_add=True)
def get_absolute_url(self):
self.pk = self.long_id
return reverse('longs:long_detail', kwargs={'pk': self.pk})
return reverse("longs:long_detail", kwargs={"pk": self.pk})
def __str__(self):
return "{} [{}] {}".format(self.long, self.author, self.created_on)
class LongCreationDefault(models.Model):
#author = models.OneToOneField(User,
# author = models.OneToOneField(User,
author = models.OneToOneField(
settings.AUTH_USER_MODEL,
related_name="long_default",
on_delete=models.CASCADE)
settings.AUTH_USER_MODEL, related_name="long_default", on_delete=models.CASCADE
)
#site = models.ManyToManyField(
# site = models.ManyToManyField(
# Site,
# blank=True,
# default=1,
# help_text="Default site to use when creating a new long")
def get_absolute_url(self):
return reverse('longs:long_create')
return reverse("longs:long_create")
class Exam(models.Model):
name = models.CharField(max_length=200)
exam_questions = SortedManyToManyField(
Long, related_name="exams", blank="true"
)
exam_questions = SortedManyToManyField(Long, related_name="exams", blank="true")
active = models.BooleanField(
help_text="If an exam should be available", default=True
@@ -262,7 +307,8 @@ class Exam(models.Model):
)
time_limit = models.IntegerField(
help_text="Exam time limit (in seconds). Default is 2100 secondse (35 minutes)", default=2100
help_text="Exam time limit (in seconds). Default is 2100 secondse (35 minutes)",
default=2100,
)
def __str__(self):
@@ -280,6 +326,7 @@ class Exam(models.Model):
def get_question_index(self, question):
return list(self.exam_questions.all()).index(question)
class CidUserAnswer(models.Model):
"""User answers by candidate"""
@@ -287,7 +334,6 @@ class CidUserAnswer(models.Model):
Long, related_name="cid_user_answers", on_delete=models.CASCADE
)
# Answers
answer_observations = models.TextField(null=True, blank=True)
answer_interpretation = models.TextField(null=True, blank=True)
@@ -295,7 +341,11 @@ class CidUserAnswer(models.Model):
answer_differential_diagnosis = models.TextField(null=True, blank=True)
answer_management = models.TextField(null=True, blank=True)
cid = models.BigIntegerField(blank=True, null=True, help_text="Candidate ID (limitied by BigIntegerField size)")
cid = models.BigIntegerField(
blank=True,
null=True,
help_text="Candidate ID (limitied by BigIntegerField size)",
)
# Each user answer is associated with a particular exam
exam = models.ForeignKey(
@@ -323,7 +373,7 @@ class CidUserAnswer(models.Model):
self.answer = self.answer.strip()
s = self.answer.lower()
s = s.translate(str.maketrans('', '', string.punctuation))
s = s.translate(str.maketrans("", "", string.punctuation))
self.answer_compare = s