diff --git a/generic/__init__.py b/generic/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/generic/admin.py b/generic/admin.py new file mode 100644 index 00000000..8c38f3f3 --- /dev/null +++ b/generic/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/generic/apps.py b/generic/apps.py new file mode 100644 index 00000000..a53a220e --- /dev/null +++ b/generic/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class GenericConfig(AppConfig): + name = 'generic' diff --git a/generic/migrations/0001_initial.py b/generic/migrations/0001_initial.py new file mode 100644 index 00000000..cf27b17e --- /dev/null +++ b/generic/migrations/0001_initial.py @@ -0,0 +1,65 @@ +# Generated by Django 3.1.3 on 2021-02-04 22:27 + +from django.db import migrations, models +import tagulous.models.models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Examination', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('examination', models.CharField(max_length=200)), + ], + options={ + 'ordering': ('examination',), + }, + ), + migrations.CreateModel( + name='Site', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('site', models.CharField(max_length=200)), + ('initials', models.CharField(max_length=200)), + ], + ), + migrations.CreateModel( + name='Sign', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255, unique=True)), + ('slug', models.SlugField()), + ('count', models.IntegerField(default=0, help_text='Internal counter of how many times this tag is in use')), + ('protected', models.BooleanField(default=False, help_text='Will not be deleted when the count reaches 0')), + ], + options={ + 'ordering': ('name',), + 'abstract': False, + 'unique_together': {('slug',)}, + }, + bases=(tagulous.models.models.BaseTagModel, models.Model), + ), + migrations.CreateModel( + name='Condition', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255, unique=True)), + ('slug', models.SlugField()), + ('count', models.IntegerField(default=0, help_text='Internal counter of how many times this tag is in use')), + ('protected', models.BooleanField(default=False, help_text='Will not be deleted when the count reaches 0')), + ], + options={ + 'ordering': ('name',), + 'abstract': False, + 'unique_together': {('slug',)}, + }, + bases=(tagulous.models.models.BaseTagModel, models.Model), + ), + ] diff --git a/generic/migrations/__init__.py b/generic/migrations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/generic/models.py b/generic/models.py new file mode 100644 index 00000000..7a23b1f6 --- /dev/null +++ b/generic/models.py @@ -0,0 +1,27 @@ +from django.db import models + +import tagulous +import tagulous.models + + +class Examination(models.Model): + examination = models.CharField(max_length=200) + + def __str__(self): + return self.examination + + class Meta: + ordering = ('examination', ) + +class Site(models.Model): + site = models.CharField(max_length=200) + initials = models.CharField(max_length=200) + + def __str__(self): + return self.site + +class Condition(tagulous.models.TagModel): + pass + +class Sign(tagulous.models.TagModel): + pass diff --git a/generic/tests.py b/generic/tests.py new file mode 100644 index 00000000..7ce503c2 --- /dev/null +++ b/generic/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/generic/views.py b/generic/views.py new file mode 100644 index 00000000..91ea44a2 --- /dev/null +++ b/generic/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/longs/forms.py b/longs/forms.py index f126262a..41675bb4 100755 --- a/longs/forms.py +++ b/longs/forms.py @@ -26,7 +26,7 @@ from django.forms.widgets import RadioSelect, TextInput, Textarea class LongAnswerForm(ModelForm): class Meta: model = CidUserAnswer - fields = ("answer_observations","answer_interpretation","answer_principle_diagnosis","answer_differential_diagnosis","answer_further_management",) + fields = ("answer_observations","answer_interpretation","answer_principle_diagnosis","answer_differential_diagnosis","answer_management",) class MarkLongQuestionForm(Form): @@ -52,7 +52,7 @@ class NoteForm(ModelForm): class LongCreationDefaultForm(ModelForm): class Meta: model = LongCreationDefault - fields = ["site"] + #fields = ["site"] exclude = ["author"] class LongSeriesForm(ModelForm): diff --git a/longs/migrations/0001_initial.py b/longs/migrations/0001_initial.py index ab3c34a7..61153367 100644 --- a/longs/migrations/0001_initial.py +++ b/longs/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 3.1.3 on 2021-02-02 19:46 +# Generated by Django 3.1.3 on 2021-02-04 22:55 from django.conf import settings import django.core.files.storage @@ -7,7 +7,6 @@ import django.db.models.deletion import django.utils.timezone import longs.models import sortedm2m.fields -import tagulous.models.models class Migration(migrations.Migration): @@ -20,23 +19,18 @@ class Migration(migrations.Migration): ] operations = [ - migrations.CreateModel( - name='Examination', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('examination', models.CharField(max_length=200)), - ], - options={ - 'ordering': ('examination',), - }, - ), migrations.CreateModel( name='Long', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('question', models.TextField(blank=True, null=True)), + ('history', models.TextField(blank=True, null=True)), ('feedback', models.TextField(blank=True, null=True)), ('sign', models.CharField(blank=True, max_length=255)), + ('model_observations', models.TextField(blank=True, null=True)), + ('model_interpretation', models.TextField(blank=True, null=True)), + ('model_principle_diagnosis', models.TextField(blank=True, null=True)), + ('model_differential_diagnosis', models.TextField(blank=True, null=True)), + ('model_further_management', models.TextField(blank=True, null=True)), ('verified', models.BooleanField(default=False)), ('created_date', models.DateTimeField(default=django.utils.timezone.now)), ('published_date', models.DateTimeField(blank=True, null=True)), @@ -49,35 +43,11 @@ class Migration(migrations.Migration): name='LongSeries', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('examination', models.ForeignKey(help_text='Name of the examination', null=True, on_delete=django.db.models.deletion.SET_NULL, to='longs.examination')), - ('long', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='long', to='longs.long')), + ('description', models.TextField(blank=True, help_text='Description of stack, for admin organisation')), + ('long', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='series', to='longs.long')), ('modality', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='series_modality', to='anatomy.modality')), ], ), - migrations.CreateModel( - name='Site', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('site', models.CharField(max_length=200)), - ('initials', models.CharField(max_length=200)), - ], - ), - migrations.CreateModel( - name='Sign', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=255, unique=True)), - ('slug', models.SlugField()), - ('count', models.IntegerField(default=0, help_text='Internal counter of how many times this tag is in use')), - ('protected', models.BooleanField(default=False, help_text='Will not be deleted when the count reaches 0')), - ], - options={ - 'ordering': ('name',), - 'abstract': False, - 'unique_together': {('slug',)}, - }, - bases=(tagulous.models.models.BaseTagModel, models.Model), - ), migrations.CreateModel( name='Note', fields=[ @@ -94,7 +64,7 @@ class Migration(migrations.Migration): ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('image', models.ImageField(storage=django.core.files.storage.FileSystemStorage(base_url='/media/longs/', location='/home/ross/scripts/sites/rad/media//longs/'), upload_to=longs.models.image_directory_path)), ('position', models.IntegerField(default=0)), - ('series', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='series', to='longs.longseries')), + ('series', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='images', to='longs.longseries')), ], ), migrations.CreateModel( @@ -102,14 +72,8 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('author', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='long_default', to=settings.AUTH_USER_MODEL)), - ('site', models.ManyToManyField(blank=True, default=1, help_text='Default site to use when creating a new long', to='longs.Site')), ], ), - migrations.AddField( - model_name='long', - name='site', - field=models.ManyToManyField(blank=True, default=1, help_text='If we know the source of the image', to='longs.Site'), - ), migrations.CreateModel( name='Exam', fields=[ @@ -122,29 +86,15 @@ class Migration(migrations.Migration): ('exam_questions', sortedm2m.fields.SortedManyToManyField(blank='true', help_text=None, related_name='exams', to='longs.Long')), ], ), - migrations.CreateModel( - name='Condition', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=255, unique=True)), - ('slug', models.SlugField()), - ('count', models.IntegerField(default=0, help_text='Internal counter of how many times this tag is in use')), - ('protected', models.BooleanField(default=False, help_text='Will not be deleted when the count reaches 0')), - ], - options={ - 'ordering': ('name',), - 'abstract': False, - 'unique_together': {('slug',)}, - }, - bases=(tagulous.models.models.BaseTagModel, models.Model), - ), migrations.CreateModel( name='CidUserAnswer', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('normal', models.BooleanField(default=False)), - ('answer', models.TextField(blank=True, max_length=500)), - ('answer_compare', models.TextField(blank=True, max_length=500)), + ('answer_observations', models.TextField(blank=True, null=True)), + ('answer_interpretation', models.TextField(blank=True, null=True)), + ('answer_principle_diagnosis', models.TextField(blank=True, null=True)), + ('answer_differential_diagnosis', models.TextField(blank=True, null=True)), + ('answer_further_management', models.TextField(blank=True, null=True)), ('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)), diff --git a/longs/migrations/0002_auto_20210204_1032.py b/longs/migrations/0002_auto_20210204_1032.py deleted file mode 100644 index ab191a2d..00000000 --- a/longs/migrations/0002_auto_20210204_1032.py +++ /dev/null @@ -1,75 +0,0 @@ -# Generated by Django 3.1.3 on 2021-02-04 10:32 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('longs', '0001_initial'), - ] - - operations = [ - migrations.RemoveField( - model_name='ciduseranswer', - name='answer', - ), - migrations.RemoveField( - model_name='ciduseranswer', - name='answer_compare', - ), - migrations.RemoveField( - model_name='ciduseranswer', - name='normal', - ), - migrations.AddField( - model_name='ciduseranswer', - name='answer_differential_diagnosis', - field=models.TextField(blank=True, null=True), - ), - migrations.AddField( - model_name='ciduseranswer', - name='answer_further_management', - field=models.TextField(blank=True, null=True), - ), - migrations.AddField( - model_name='ciduseranswer', - name='answer_interpretation', - field=models.TextField(blank=True, null=True), - ), - migrations.AddField( - model_name='ciduseranswer', - name='answer_observations', - field=models.TextField(blank=True, null=True), - ), - migrations.AddField( - model_name='ciduseranswer', - name='answer_principle_diagnosis', - field=models.TextField(blank=True, null=True), - ), - migrations.AddField( - model_name='long', - name='model_differential_diagnosis', - field=models.TextField(blank=True, null=True), - ), - migrations.AddField( - model_name='long', - name='model_further_management', - field=models.TextField(blank=True, null=True), - ), - migrations.AddField( - model_name='long', - name='model_interpretation', - field=models.TextField(blank=True, null=True), - ), - migrations.AddField( - model_name='long', - name='model_observations', - field=models.TextField(blank=True, null=True), - ), - migrations.AddField( - model_name='long', - name='model_principle_diagnosis', - field=models.TextField(blank=True, null=True), - ), - ] diff --git a/longs/migrations/0002_auto_20210204_2258.py b/longs/migrations/0002_auto_20210204_2258.py new file mode 100644 index 00000000..f9e76f11 --- /dev/null +++ b/longs/migrations/0002_auto_20210204_2258.py @@ -0,0 +1,24 @@ +# Generated by Django 3.1.3 on 2021-02-04 22:58 + +from django.db import migrations +import tagulous.models.fields + + +class Migration(migrations.Migration): + + dependencies = [ + ('generic', '0001_initial'), + ('longs', '0001_initial'), + ] + + operations = [ + migrations.RemoveField( + model_name='long', + name='sign', + ), + migrations.AddField( + model_name='long', + name='sign', + field=tagulous.models.fields.TagField(_set_tag_meta=True, blank=True, help_text='Radiological signs in the question', to='generic.Sign'), + ), + ] diff --git a/longs/migrations/0003_auto_20210204_2105.py b/longs/migrations/0003_auto_20210204_2105.py deleted file mode 100644 index 62a3be04..00000000 --- a/longs/migrations/0003_auto_20210204_2105.py +++ /dev/null @@ -1,23 +0,0 @@ -# Generated by Django 3.1.3 on 2021-02-04 21:05 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('longs', '0002_auto_20210204_1032'), - ] - - operations = [ - migrations.RenameField( - model_name='long', - old_name='question', - new_name='history', - ), - migrations.AddField( - model_name='longseries', - name='description', - field=models.TextField(blank=True, help_text='Description of stack, for admin organisation'), - ), - ] diff --git a/longs/migrations/0003_long_condition.py b/longs/migrations/0003_long_condition.py new file mode 100644 index 00000000..d1c90d07 --- /dev/null +++ b/longs/migrations/0003_long_condition.py @@ -0,0 +1,20 @@ +# Generated by Django 3.1.3 on 2021-02-04 22:58 + +from django.db import migrations +import tagulous.models.fields + + +class Migration(migrations.Migration): + + dependencies = [ + ('generic', '0001_initial'), + ('longs', '0002_auto_20210204_2258'), + ] + + operations = [ + migrations.AddField( + model_name='long', + name='condition', + field=tagulous.models.fields.TagField(_set_tag_meta=True, blank=True, help_text='Associated condition. Will allow searching / filtering and tips / hints to be displayed. Conditions with spaces must be enclosed in quotes "..."', to='generic.Condition'), + ), + ] diff --git a/longs/migrations/0004_auto_20210204_2259.py b/longs/migrations/0004_auto_20210204_2259.py new file mode 100644 index 00000000..baf0e9e2 --- /dev/null +++ b/longs/migrations/0004_auto_20210204_2259.py @@ -0,0 +1,24 @@ +# Generated by Django 3.1.3 on 2021-02-04 22:59 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('generic', '0001_initial'), + ('longs', '0003_long_condition'), + ] + + operations = [ + migrations.AddField( + model_name='long', + name='site', + field=models.ManyToManyField(blank=True, default=1, help_text='If we know the source of the image', to='generic.Site'), + ), + migrations.AddField( + model_name='longcreationdefault', + name='site', + field=models.ManyToManyField(blank=True, default=1, help_text='Default site to use when creating a new long', to='generic.Site'), + ), + ] diff --git a/longs/migrations/0005_auto_20210205_0955.py b/longs/migrations/0005_auto_20210205_0955.py new file mode 100644 index 00000000..cbca7f50 --- /dev/null +++ b/longs/migrations/0005_auto_20210205_0955.py @@ -0,0 +1,18 @@ +# Generated by Django 3.1.3 on 2021-02-05 09:55 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('longs', '0004_auto_20210204_2259'), + ] + + operations = [ + migrations.RenameField( + model_name='long', + old_name='model_further_management', + new_name='model_management', + ), + ] diff --git a/longs/migrations/0006_auto_20210205_0958.py b/longs/migrations/0006_auto_20210205_0958.py new file mode 100644 index 00000000..46b2d68a --- /dev/null +++ b/longs/migrations/0006_auto_20210205_0958.py @@ -0,0 +1,18 @@ +# Generated by Django 3.1.3 on 2021-02-05 09:58 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('longs', '0005_auto_20210205_0955'), + ] + + operations = [ + migrations.RenameField( + model_name='ciduseranswer', + old_name='answer_further_management', + new_name='answer_management', + ), + ] diff --git a/longs/models.py b/longs/models.py index 60f87028..e9c218e9 100644 --- a/longs/models.py +++ b/longs/models.py @@ -1,6 +1,5 @@ from django.db.models.fields.files import ImageField from django.db.models.fields.related import ForeignKey -from anatomy.models import Modality from django.db import models from django.utils import timezone import tagulous @@ -20,6 +19,10 @@ from sortedm2m.fields import SortedManyToManyField import string +from anatomy.models import Modality + +from generic.models import Examination, Site, Condition, Sign + image_storage = FileSystemStorage( # Physical file location ROOT location=u"{0}/longs/".format(settings.MEDIA_ROOT), @@ -32,31 +35,6 @@ def image_directory_path(instance, filename): -class Examination(models.Model): - examination = models.CharField(max_length=200) - - def __str__(self): - return self.examination - - class Meta: - ordering = ('examination', ) - - -class Site(models.Model): - site = models.CharField(max_length=200) - initials = models.CharField(max_length=200) - - def __str__(self): - return self.site - - -class Condition(tagulous.models.TagModel): - pass - -class Sign(tagulous.models.TagModel): - pass - - class Long(models.Model): #author = models.ForeignKey('auth.User', on_delete=models.CASCADE) #image = models.ImageField() @@ -64,23 +42,23 @@ class Long(models.Model): feedback = models.TextField(null=True, blank=True) - #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 \"...\"" - #) + 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 \"...\"" + ) - sign = models.CharField(max_length=255, blank=True) - #sign = tagulous.models.TagField( - # to=Sign, blank=True, help_text='Radiological signs in the question') + #sign = models.CharField(max_length=255, blank=True) + sign = tagulous.models.TagField( + to=Sign, blank=True, help_text='Radiological signs in the question') # Model answers model_observations = models.TextField(null=True, blank=True) model_interpretation = models.TextField(null=True, blank=True) model_principle_diagnosis = models.TextField(null=True, blank=True) model_differential_diagnosis = models.TextField(null=True, blank=True) - model_further_management = models.TextField(null=True, blank=True) + model_management = models.TextField(null=True, blank=True) DEFAULT_SITE_ID = 1 @@ -147,8 +125,8 @@ class LongSeriesImage(models.Model): class LongSeries(models.Model): 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", 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", related_name="series", on_delete=models.SET_NULL, null=True) description = models.TextField(blank=True, help_text="Description of stack, for admin organisation") @@ -263,8 +241,7 @@ class CidUserAnswer(models.Model): answer_interpretation = models.TextField(null=True, blank=True) answer_principle_diagnosis = models.TextField(null=True, blank=True) answer_differential_diagnosis = models.TextField(null=True, blank=True) - answer_further_management = 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)") diff --git a/rad/settings.py b/rad/settings.py index 5140d53c..1371a688 100644 --- a/rad/settings.py +++ b/rad/settings.py @@ -30,6 +30,7 @@ ALLOWED_HOSTS = ["localhost", "127.0.0.1", "161.35.163.87", "penracourses.org.uk # Application definition INSTALLED_APPS = [ + 'generic', 'anatomy', 'physics', 'rapids',