diff --git a/anatomy/serializers.py b/anatomy/serializers.py deleted file mode 100644 index 8baf5fc0..00000000 --- a/anatomy/serializers.py +++ /dev/null @@ -1,10 +0,0 @@ -# serializers.py -from rest_framework import serializers, permissions - - -from .models import Exam - -class ExamSerializer(serializers.HyperlinkedModelSerializer): - class Meta: - model = Exam - fields = ('name', 'id', 'active', "publish_results") diff --git a/anatomy/views.py b/anatomy/views.py index 42ac52c5..b2736733 100644 --- a/anatomy/views.py +++ b/anatomy/views.py @@ -80,10 +80,6 @@ from django.template.defaulttags import register from generic.mixins import CheckCanEditMixin, SuperuserRequiredMixin -from rest_framework import viewsets, permissions - -from .serializers import ExamSerializer - class AuthorOrCheckerRequiredMixin(object): def get_object(self, *args, **kwargs): @@ -818,22 +814,6 @@ class ExamDelete(AuthorOrCheckerRequiredMixin, ExamDeleteBase): -#class ExamViewSet(RevisionMixin, viewsets.ModelViewSet): -# # queryset = Exam.objects.all().order_by('name') -# serializer_class = ExamSerializer -# permission_classes = [permissions.IsAuthenticated] -# -# def get_queryset(self): -# """ -# This view should return a list exams available to a user. -# """ -# user = self.request.user -# if user.groups.filter(name="anatomy_checker").exists(): -# return Exam.objects.all() -# -# return Exam.objects.filter(author__id=user.id) - - class ExamAuthorUpdate(RevisionMixin, CheckCanEditMixin, LoginRequiredMixin, AuthorRequiredMixin, UpdateView): model = Exam form_class = ExamAuthorForm diff --git a/atlas/forms.py b/atlas/forms.py index cfdb4d70..93c1fb57 100755 --- a/atlas/forms.py +++ b/atlas/forms.py @@ -55,7 +55,7 @@ from tinymce.widgets import TinyMCE from dal import autocomplete -from autocomplete import widgets as htmx_widgets +from autocomplete import widgets as htmx_widgets, Autocomplete, AutocompleteWidget, ModelAutocomplete, register as autocomplete_register import logging @@ -782,11 +782,17 @@ class UncategorisedDicomForm(ModelForm): # ) # } +class ConditionAutocomplete(ModelAutocomplete): + model = Condition + search_attrs = ["name"] + class ConditionAutocompleteForm(Form): - condition = ModelChoiceField(queryset=Condition.objects.all(), widget=htmx_widgets.Autocomplete( - name="conditions", options=dict(model=Condition) + condition = ModelChoiceField(queryset=Condition.objects.all(), widget=AutocompleteWidget( + ac_class=ConditionAutocomplete#, options=dict(model=Condition) + )) +autocomplete_register(ConditionAutocomplete) class CaseCollectionAuthorForm(ExamAuthorFormMixin): class Meta(ExamAuthorFormMixin.Meta): diff --git a/atlas/serializers.py b/atlas/serializers.py deleted file mode 100644 index f29efdb9..00000000 --- a/atlas/serializers.py +++ /dev/null @@ -1,2 +0,0 @@ -# serializers.py -from rest_framework import serializers, permissions diff --git a/atlas/views.py b/atlas/views.py index b4c6e29b..37579bfa 100755 --- a/atlas/views.py +++ b/atlas/views.py @@ -118,7 +118,7 @@ from .filters import ( from django_tables2 import SingleTableView, SingleTableMixin from django_filters.views import FilterView -from autocomplete import HTMXAutoComplete +#from autocomplete import HTMXAutoComplete from .decorators import ( @@ -156,8 +156,6 @@ from reversion.views import RevisionMixin import reversion -from rest_framework import viewsets - import os import difflib diff --git a/generic/templates/generic/examcollection_detail.html b/generic/templates/generic/examcollection_detail.html index 282ac82b..77228411 100755 --- a/generic/templates/generic/examcollection_detail.html +++ b/generic/templates/generic/examcollection_detail.html @@ -24,55 +24,47 @@ {% if object.anatomy_exams.all %}

Anatomy Exams:

- + {% with exams=object.anatomy_exams.all app_name="anatomy" %} + {% include "exam_list.html#exam-list" %} + {% endwith %} + View exam list {% endif %} {% if object.longs_exams.all %}

Longs Exams:

- + {% with exams=object.longs_exams.all app_name="longs" %} + {% include "exam_list.html#exam-list" %} + {% endwith %} View exam list {% endif %} {% if object.rapids_exams.all %}

Rapids Exams:

- + {% with exams=object.rapids_exams.all app_name="rapids" %} + {% include "exam_list.html#exam-list" %} + {% endwith %} View exam list {% endif %} {% if object.physics_exams.all %}

Physics Exams:

- + {% with exams=object.physics_exams.all app_name="physics" %} + {% include "exam_list.html#exam-list" %} + {% endwith %} View exam list {% endif %} {% if object.sbas_exams.all %}

SBAs Exams:

- + {% with exams=object.sbas_exams.all app_name="sbas" %} + {% include "exam_list.html#exam-list" %} + {% endwith %} View exam list {% endif %} + {% include 'exam_overview_js.html' %} {% endblock %} diff --git a/longs/serializers.py b/longs/serializers.py deleted file mode 100644 index a447defc..00000000 --- a/longs/serializers.py +++ /dev/null @@ -1,11 +0,0 @@ -# serializers.py -from rest_framework import serializers, permissions - - -from .models import Exam - -class ExamSerializer(serializers.HyperlinkedModelSerializer): - class Meta: - model = Exam - fields = ('name', 'id', 'active', "publish_results") - permission_classes = [permissions.IsAuthenticated] \ No newline at end of file diff --git a/longs/views.py b/longs/views.py index 6adecd23..a536ac31 100755 --- a/longs/views.py +++ b/longs/views.py @@ -94,10 +94,6 @@ from reversion.views import RevisionMixin import reversion -from rest_framework import viewsets - -from .serializers import ExamSerializer - from zipview.views import BaseZipView import os @@ -1005,12 +1001,6 @@ class ExamGroupsUpdate(ExamGroupsUpdateBase): model = Exam form_class = ExamGroupsForm - -# class ExamViewSet(RevisionMixin, viewsets.ModelViewSet): -# queryset = Exam.objects.all().order_by("name") -# serializer_class = ExamSerializer - - def question_json_unbased(request, pk): """ No (file based) caching is enabled for unbased quesitons diff --git a/physics/views.py b/physics/views.py index fc145fd9..e005a3ad 100644 --- a/physics/views.py +++ b/physics/views.py @@ -54,9 +54,6 @@ from generic.views import ( exam_inactive, ) -from rest_framework import viewsets, permissions -from rest_framework.pagination import PageNumberPagination - from django.core.exceptions import PermissionDenied from .forms import ExamGroupsForm, ExamMarkerForm, UserAnswerForm, ExamAuthorForm, ExamForm diff --git a/rad/settings.py b/rad/settings.py index e5f4f11e..9a1faf64 100644 --- a/rad/settings.py +++ b/rad/settings.py @@ -72,7 +72,6 @@ INSTALLED_APPS = [ "django.contrib.staticfiles", "django.contrib.postgres", "dbbackup", - "rest_framework", "tinymce", "django_unused_media", "django_htmx", @@ -83,6 +82,7 @@ INSTALLED_APPS = [ 'django_jsonforms', 'django_svelte_jsoneditor', 'django_psutil_dash', + 'template_partials', ] diff --git a/rad/urls.py b/rad/urls.py index 8d626561..01ac6500 100644 --- a/rad/urls.py +++ b/rad/urls.py @@ -34,7 +34,8 @@ from generic import views as generic_views from django.conf.urls import handler400, handler403, handler404, handler500 from .api import api -from autocomplete import HTMXAutoComplete +from autocomplete import urls as autocomplete_urls + urlpatterns = [ @@ -153,7 +154,8 @@ urlpatterns = [ path("privacy/", views.privacy_view, name="privacy"), path("about/", views.about_view, name="about"), # path('select2/', include('select2.urls')), - *HTMXAutoComplete.url_dispatcher('ac'), + + path("ac/", autocomplete_urls), path('psutil/', psutil_urlpatterns(), name='psutil'), path("cimar/", views.cimar, name="cimar"), diff --git a/rapids/serializers.py b/rapids/serializers.py deleted file mode 100644 index 65f7d91e..00000000 --- a/rapids/serializers.py +++ /dev/null @@ -1,39 +0,0 @@ -# serializers.py -from rest_framework import serializers, permissions - - -from .models import Exam, Answer, Rapid, UserAnswer - -class ExamSerializer(serializers.HyperlinkedModelSerializer): - class Meta: - model = Exam - fields = ('name', 'id', 'active', "publish_results") - -class QuestionAnswerSerializer(serializers.HyperlinkedModelSerializer): - #question = serializers.HyperlinkedRelatedField(view_name='rapid-detail', - # read_only=True - # ) - class Meta: - model = Answer - fields = ('id', 'question', 'answer', "answer_compare", "status") - view_name = "rapid-exam" - -class UserAnswerSerializer(serializers.HyperlinkedModelSerializer): - exam = serializers.HyperlinkedRelatedField(view_name='rapid-exam-detail', - read_only=True - ) - class Meta: - model = UserAnswer - fields = ('id', 'question', 'normal', "answer", "answer_compare", "cid", "user", "exam", "created", "updated") - -class RapidSerializer(serializers.ModelSerializer): - class Meta: - model = Rapid - fields = ('id', 'question', 'normal', "abnormality", "region", "laterality", "examination", "exams", "author", "open_access") - view_name = "rapid-detail" - -class RapidLateralitySerializer(serializers.ModelSerializer): - class Meta: - model = Rapid - fields = ('id', "laterality") - view_name = "rapid-laterality" \ No newline at end of file diff --git a/rapids/views.py b/rapids/views.py index 264111de..dca60576 100755 --- a/rapids/views.py +++ b/rapids/views.py @@ -83,18 +83,6 @@ from django.forms.models import model_to_dict from rapids.forms import RapidCreationDefaultForm from rapids.models import RapidCreationDefault - -from rest_framework import viewsets, permissions, mixins -from rest_framework.pagination import PageNumberPagination - -from .serializers import ( - ExamSerializer, - QuestionAnswerSerializer, - RapidLateralitySerializer, - RapidSerializer, - UserAnswerSerializer, -) - from generic.mixins import CheckCanEditMixin, SuperuserRequiredMixin from dal import autocomplete @@ -797,92 +785,6 @@ class UserAnswerDelete(SuperuserRequiredMixin, DeleteView): success_url = reverse_lazy("rapids:user_answer_table_view") -class LargeResultsSetPagination(PageNumberPagination): - page_size = 1000 - page_size_query_param = "page_size" - max_page_size = 10000 - - -class StandardResultsSetPagination(PageNumberPagination): - page_size = 100 - page_size_query_param = "page_size" - max_page_size = 1000 - - -class ExamViewSet(RevisionMixin, viewsets.ModelViewSet): - # queryset = Exam.objects.all().order_by('name') - serializer_class = ExamSerializer - - def get_queryset(self): - """ - This view should return a list exams available to a user. - """ - user = self.request.user - if user.groups.filter(name="rapid_checker").exists(): - return Exam.objects.filter(archive=False).order_by("name") - - return Exam.objects.filter(author__id=user.id, archive=False).order_by("name") - - -# class QuestionAnswerViewSet(viewsets.ModelViewSet): -# queryset = Answer.objects.all() # .order_by('name') -# serializer_class = QuestionAnswerSerializer -# permission_classes = [permissions.IsAuthenticated] -# -# -# class UserAnswerViewSet(viewsets.ModelViewSet): -# queryset = UserAnswer.objects.all() # .order_by('name') -# serializer_class = UserAnswerSerializer -# permission_classes = [permissions.IsAuthenticated] - - -# class RapidViewSet( -# RevisionMixin, -# mixins.CreateModelMixin, -# mixins.RetrieveModelMixin, -# mixins.UpdateModelMixin, -# mixins.ListModelMixin, -# mixins.DestroyModelMixin, -# viewsets.GenericViewSet, -# ): -# queryset = Rapid.objects.all() # .order_by('name') -# serializer_class = RapidSerializer -# permission_classes = [permissions.IsAuthenticated] -# pagination_class = StandardResultsSetPagination - - -# class AddSuggestedAnswer(LoginRequiredMixin, CreateView): -# model = QuestionNote -# form_class = QuestionNoteForm -# -# #fields = ("author", "note_type", "note") -# -# -# def get_form_kwargs(self): -# kwargs = super(AddQuestionNote, self).get_form_kwargs() -# # update the kwargs for the form init method with yours -# kwargs.update(self.kwargs) # self.kwargs contains all url conf params -# return kwargs -# -# def get_initial(self): -# pk = self.kwargs["pk"] -# question_type = self.kwargs["question_type"] -# if question_type == "rapid": -# question = Rapid -# content_type = ContentType.objects.get(model="rapid") -# elif question_type == "anatomy": -# question = AnatomyQuestion -# content_type = ContentType.objects.get(model="anatomyquestion") -# elif question_type == "long": -# question = Long -# content_type = ContentType.objects.get(model="long") -# else: -# raise PermissionError() -# -# get_object_or_404(question, pk=pk) -# return { "content_type" : content_type, -# "object_id" : pk } - GenericViews = GenericViewBase("rapids", Rapid, UserAnswer, Exam) diff --git a/requirements.txt b/requirements.txt index b325395d..e3987902 100644 --- a/requirements.txt +++ b/requirements.txt @@ -51,4 +51,5 @@ pylibjpeg-libjpeg git+https://github.com/xkjq/django-jsonforms.git@bump-json-editor-lib django_svelte_jsoneditor psutil -django-psutil-dash \ No newline at end of file +django-psutil-dash +django-template-partials \ No newline at end of file diff --git a/sbas/views.py b/sbas/views.py index 4ab491c8..5185f949 100644 --- a/sbas/views.py +++ b/sbas/views.py @@ -54,9 +54,6 @@ from generic.views import ( exam_inactive, ) -from rest_framework import viewsets, permissions -from rest_framework.pagination import PageNumberPagination - from django.core.exceptions import PermissionDenied from .tables import QuestionTable, UserAnswerTable @@ -411,22 +408,6 @@ class ExamDelete(AuthorOrCheckerRequiredMixin, ExamDeleteBase): model = Exam -# class ExamViewSet(RevisionMixin, viewsets.ModelViewSet): -# # queryset = Exam.objects.all().order_by('name') -# serializer_class = ExamSerializer -# permission_classes = [permissions.IsAuthenticated] -# -# def get_queryset(self): -# """ -# This view should return a list exams available to a user. -# """ -# user = self.request.user -# if user.groups.filter(name="sbas_checker").exists(): -# return Exam.objects.all() -# -# return Exam.objects.filter(author__id=user.id) - - class ExamAuthorUpdate( RevisionMixin, CheckCanEditMixin, LoginRequiredMixin, AuthorRequiredMixin, UpdateView ): diff --git a/templates/exam_list.html b/templates/exam_list.html index 7dfc5935..61cf3a88 100644 --- a/templates/exam_list.html +++ b/templates/exam_list.html @@ -1,102 +1,31 @@ {% extends app_name|add:'/base.html' %} -{% block content %} -

Examinations

+{% load partials %} - {% if collection %} -

Collection: {{collection.name}}

- {% endif %} - -
- Help - {% if collection %} -

This page shows all the examinations within the collection "{{collection.name}}".

- {% else %} -

This page shows the currently active examinations (that you have access to manage).

- {% endif %} +{% partialdef exam-list %} + -

Exams that are active will be available for candidates to take.

- -

Once candidates have completed the exam (or submitted some answers) they will immediately be able to view their answers on the platoform. They will not be able to see the correct answers (or their scores) until the exams results have been published.

- -

A users submitted answers will remain available to the user until the exam is archived. Once an exam is archived the user will no longer be able to view their submitted answers.

- -

Supervisors will have access to all exam results (including archived exams) for which they have access (when "results supervisor visible" is set to true or the user has shared their results).

-
-
- Exams:
- - -{% comment %} Inactive exams:
- {% endcomment %} - - - - {% if collection %} - - {% else %} - {% if view_all %} - Hide archived - {% else %} - View all - {% endif %} - {% endif %} -
- {% include 'exam_overview_js.html' %} +{% endpartialdef %} + +{% block content %} +

Examinations

+ + {% if collection %} +

Collection: {{collection.name}}

+ {% endif %} + +
+ Help + {% if collection %} +

This page shows all the examinations within the collection "{{collection.name}}".

+ {% else %} +

This page shows the currently active examinations (that you have access to manage).

+ {% endif %} + + +

Exams that are active will be available for candidates to take.

+ +

Once candidates have completed the exam (or submitted some answers) they will immediately be able to view their answers on the platoform. They will not be able to see the correct answers (or their scores) until the exams results have been published.

+ +

A users submitted answers will remain available to the user until the exam is archived. Once an exam is archived the user will no longer be able to view their submitted answers.

+ +

Supervisors will have access to all exam results (including archived exams) for which they have access (when "results supervisor visible" is set to true or the user has shared their results).

+
+
+ Exams:
+ {% partial exam-list %} + +{% comment %} Inactive exams:
+ {% endcomment %} + + + + {% if collection %} + + {% else %} + {% if view_all %} + Hide archived + {% else %} + View all + {% endif %} + {% endif %} +
+ {% include 'exam_overview_js.html' %} {% endblock %}