149 lines
11 KiB
Python
149 lines
11 KiB
Python
# Generated by Django 5.1.4 on 2025-03-31 10:53
|
|
|
|
import django.core.validators
|
|
import django.db.models.deletion
|
|
import django.utils.timezone
|
|
import generic.mixins
|
|
import shorts.models
|
|
from django.conf import settings
|
|
from django.db import migrations, models
|
|
|
|
|
|
class Migration(migrations.Migration):
|
|
|
|
initial = True
|
|
|
|
dependencies = [
|
|
('generic', '0025_cimarseriesthumbnail'),
|
|
('rapids', '0016_exam_results_supervisor_visible'),
|
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
|
]
|
|
|
|
operations = [
|
|
migrations.CreateModel(
|
|
name='Exam',
|
|
fields=[
|
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
('name', models.CharField(help_text='Name of the exam/collection', max_length=200)),
|
|
('start_date', models.DateTimeField(blank=True, help_text='Date (and time) the exam/collection starts', null=True)),
|
|
('end_date', models.DateTimeField(blank=True, help_text='Date (and time) the exam/collection ends', null=True)),
|
|
('restrict_to_dates', models.BooleanField(default=False, help_text='If the exam/collection should only be taken between the start and end date times')),
|
|
('active', models.BooleanField(default=False, help_text='If an exam/collection should be available to take')),
|
|
('publish_results', models.BooleanField(default=False, help_text='If an exam/collections results should be available')),
|
|
('archive', models.BooleanField(default=False, help_text='Archived exams/collections will remain on the test system but will not be displayed by default')),
|
|
('open_access', models.BooleanField(default=False, help_text='If the exam/collection is freely accessible (to view and edit on the test system)')),
|
|
('candidates_only', models.BooleanField(default=True, help_text='If the exam/collection is only available to candidates who have been added')),
|
|
('authors_only', models.BooleanField(default=False, help_text='If true only exam/collection authors will be able to view.')),
|
|
('results_supervisor_visible', models.BooleanField(default=False, help_text='If true the results will be visible to supervisors without candidate approval.')),
|
|
('exam_open_access', models.BooleanField(default=False, help_text='Set to true if you want any registered user to be able to take the exam.')),
|
|
('exam_mode', models.BooleanField(default=False, help_text='If an exam should be taken in exam mode (users results will be submited to the server for marking)')),
|
|
('include_history', models.BooleanField(default=False, help_text='If an exam should include history when taking')),
|
|
('recreate_json', models.BooleanField(default=False, help_text='If the json cache needs updating')),
|
|
('json_creation_time', models.DateTimeField(blank=True, default=None, null=True)),
|
|
('exam_json_id', models.IntegerField(default=1, help_text='auto incrementing field when json recreated')),
|
|
('stats_mean', models.FloatField(default=0)),
|
|
('stats_mode', models.CharField(default=0, max_length=25)),
|
|
('stats_median', models.FloatField(default=0)),
|
|
('stats_candidates', models.FloatField(default=0)),
|
|
('stats_min', models.FloatField(default=0)),
|
|
('stats_max', models.FloatField(default=0)),
|
|
('stats_max_possible', models.FloatField(default=0)),
|
|
('stats_graph', models.TextField(default=0)),
|
|
('user_scores', models.JSONField(blank=True, default=dict)),
|
|
('exam_results_emailed', models.DateTimeField(blank=True, default=None, null=True)),
|
|
('time_limit', models.IntegerField(default=7200, help_text='Exam time limit (in seconds). Default is 2 hours')),
|
|
('author', models.ManyToManyField(blank=True, help_text='Author of exam', related_name='shorts_exam_author', to=settings.AUTH_USER_MODEL)),
|
|
('cid_user_groups', models.ManyToManyField(blank=True, help_text='These groups define which candidates are able to be added to the exams/collection.', related_name='shorts_cid_user_groups', to='generic.cidusergroup')),
|
|
('examcollection', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='shorts_exams', to='generic.examcollection')),
|
|
('markers', models.ManyToManyField(blank=True, help_text='Authorised markers for the exam', related_name='shorts_exam_markers', to=settings.AUTH_USER_MODEL)),
|
|
('user_user_groups', models.ManyToManyField(blank=True, help_text='These groups define which candidates are able to be added to the exams/collection.', related_name='shorts_user_user_groups', to='generic.userusergroup')),
|
|
('valid_cid_users', models.ManyToManyField(blank=True, related_name='shorts_exams', to='generic.ciduser')),
|
|
('valid_user_users', models.ManyToManyField(blank=True, related_name='user_shorts_exams', to=settings.AUTH_USER_MODEL)),
|
|
],
|
|
options={
|
|
'abstract': False,
|
|
},
|
|
bases=(models.Model, generic.mixins.AuthorMixin),
|
|
),
|
|
migrations.CreateModel(
|
|
name='Question',
|
|
fields=[
|
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
('authors_only', models.BooleanField(default=False, help_text='If true only question authors will be able to view.')),
|
|
('created_date', models.DateTimeField(default=django.utils.timezone.now)),
|
|
('open_access', models.BooleanField(default=True, help_text='If a question should be freely available to browse')),
|
|
('feedback', models.TextField(blank=True, help_text='Question Feedback', null=True)),
|
|
('history', models.TextField(blank=True, null=True)),
|
|
('laterality', models.CharField(choices=[('NONE', 'None'), ('LEFT', 'Left'), ('RIGHT', 'Right'), ('BILAT', 'Bilateral')], default='NONE', help_text='Applies to the answer, not the examination', max_length=20)),
|
|
('abnormality', models.ManyToManyField(blank=True, help_text='The abnormality (laterality and region independent). Used for categorisation but does not affect the answer', to='rapids.abnormality')),
|
|
('author', models.ManyToManyField(blank=True, help_text='Author of question', related_name='shorts_authored_questions', to=settings.AUTH_USER_MODEL)),
|
|
('examination', models.ManyToManyField(help_text='Name of the (primary) examination', to='rapids.examination')),
|
|
('region', models.ManyToManyField(blank=True, help_text='Region of the abnormality (laterality independent)', to='rapids.region')),
|
|
],
|
|
options={
|
|
'abstract': False,
|
|
},
|
|
bases=(models.Model, generic.mixins.AuthorMixin, generic.mixins.QuestionMixin),
|
|
),
|
|
migrations.CreateModel(
|
|
name='ExamQuestionDetail',
|
|
fields=[
|
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
('sort_order', models.IntegerField(default=1000)),
|
|
('exam', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='shorts.exam')),
|
|
('question', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='shorts.question')),
|
|
],
|
|
options={
|
|
'ordering': ('sort_order',),
|
|
},
|
|
),
|
|
migrations.AddField(
|
|
model_name='exam',
|
|
name='exam_questions',
|
|
field=models.ManyToManyField(related_name='exams', through='shorts.ExamQuestionDetail', to='shorts.question'),
|
|
),
|
|
migrations.CreateModel(
|
|
name='QuestionImage',
|
|
fields=[
|
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
('image', models.FileField(upload_to=shorts.models.image_directory_path)),
|
|
('image_annotations', models.TextField(blank=True, help_text='Stores a JSON representation of annotations to be applied by cornerstonetools', null=True)),
|
|
('feedback_image', models.BooleanField(default=False)),
|
|
('filename', models.CharField(blank=True, help_text='Name of the original file when uploaded', max_length=255, null=True)),
|
|
('description', models.CharField(blank=True, max_length=255, null=True)),
|
|
('image_md5_hash', models.CharField(blank=True, max_length=32, null=True)),
|
|
('is_dicom', models.BooleanField(default=False)),
|
|
('question', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='images', to='shorts.question')),
|
|
],
|
|
),
|
|
migrations.CreateModel(
|
|
name='SampleAnswer',
|
|
fields=[
|
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
('answer', models.TextField()),
|
|
('score', models.IntegerField(blank=True, default=0, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(5)])),
|
|
('proposed', models.BooleanField(default=False)),
|
|
('question', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='sample_answers', to='shorts.question')),
|
|
],
|
|
),
|
|
migrations.CreateModel(
|
|
name='UserAnswer',
|
|
fields=[
|
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
('cid', models.BigIntegerField(blank=True, help_text='Candidate ID (limitied by BigIntegerField size)', null=True)),
|
|
('created', models.DateTimeField(auto_now_add=True)),
|
|
('updated', models.DateTimeField(auto_now=True)),
|
|
('answer', models.TextField(blank=True)),
|
|
('score', models.IntegerField(blank=True, default=0, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(5)])),
|
|
('callstate', models.CharField(blank=True, choices=[('C', 'Correct Call'), ('O', 'Overcall'), ('U', 'Undercall'), ('W', 'Incorrect Call'), ('P', 'Partial Call')], max_length=1, null=True)),
|
|
('exam', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='cid_user_answers', to='shorts.exam')),
|
|
('question', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='cid_user_answers', to='shorts.question')),
|
|
('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='user_shorts_user_answers', to=settings.AUTH_USER_MODEL)),
|
|
],
|
|
options={
|
|
'ordering': ['cid'],
|
|
'abstract': False,
|
|
},
|
|
),
|
|
]
|