fix a few missing things

This commit is contained in:
Ross
2024-08-19 13:16:47 +01:00
parent 3cb84fb7c4
commit 58eeb4f442
11 changed files with 59 additions and 23 deletions
+1
View File
@@ -53,6 +53,7 @@ urlpatterns = [
"exam/<int:exam_pk>/<int:sk>/mark/review", views.mark_review, name="mark_review" "exam/<int:exam_pk>/<int:sk>/mark/review", views.mark_review, name="mark_review"
), ),
path("exam/<int:pk>/markers", views.ExamMarkersUpdate.as_view(), name="exam_markers"), path("exam/<int:pk>/markers", views.ExamMarkersUpdate.as_view(), name="exam_markers"),
path("exam/<int:pk>/groups", views.ExamGroupsUpdate.as_view(), name="exam_groups_edit"),
path("exam/<int:pk>/authors", views.ExamAuthorUpdate.as_view(), name="exam_authors"), path("exam/<int:pk>/authors", views.ExamAuthorUpdate.as_view(), name="exam_authors"),
path("exam/create", views.ExamCreate.as_view(), name="exam_create"), path("exam/create", views.ExamCreate.as_view(), name="exam_create"),
path("exam/<int:exam_id>/clone", views.ExamClone.as_view(), name="exam_clone"), path("exam/<int:exam_id>/clone", views.ExamClone.as_view(), name="exam_clone"),
+4 -1
View File
@@ -57,7 +57,7 @@ from autocomplete import widgets as htmx_widgets
import logging import logging
from generic.forms import ExamAuthorFormMixin from generic.forms import ExamAuthorFormMixin, ExamGroupsFormMixin
from crispy_forms.helper import FormHelper from crispy_forms.helper import FormHelper
@@ -749,6 +749,9 @@ class SeriesAuthorForm(ExamAuthorFormMixin):
class Meta(ExamAuthorFormMixin.Meta): class Meta(ExamAuthorFormMixin.Meta):
model = Series model = Series
class ExamGroupsForm(ExamGroupsFormMixin):
class Meta(ExamGroupsFormMixin.Meta):
model = CaseCollection
class AnswerJSONForm(Form): class AnswerJSONForm(Form):
+8
View File
@@ -1188,6 +1188,14 @@ class SelfReview(models.Model):
review_date = models.DateTimeField(auto_now_add=True) review_date = models.DateTimeField(auto_now_add=True)
review_update_date = models.DateTimeField(auto_now=True) review_update_date = models.DateTimeField(auto_now=True)
def __str__(self) -> str:
date = self.review_date
if self.review_update_date is not None:
date = self.review_update_date
return f"Self review: {date:%Y-%m-%d} / {self.user_exam.exam} - {self.case}"
def get_absolute_url(self): def get_absolute_url(self):
return self.user_exam.exam.get_case_take_url(self.case) return self.user_exam.exam.get_case_take_url(self.case)
@@ -67,20 +67,20 @@
Images Images
</summary> </summary>
{% for series, prior, relation in series_to_load %} {% for series, prior, relation in series_to_load %}
<span class="series-block <span class="series-block
{% if prior %} {% if prior %}
prior prior
{% endif %} {% endif %}
"> ">
<a href="#" onclick='window.loadDicomViewer(window.images[{{forloop.counter0}}])'> <a href="#" onclick='window.loadDicomViewer(window.images[{{forloop.counter0}}])'>
<span> <span>
<span class="series-block-series-number">Series {{ forloop.counter }}:</span> <span class="series-block-series-number">Series {{ forloop.counter }}:</span>
{{series.get_block}} {{series.get_block}}
</span> </span>
{% if prior %} {% if prior %}
<br/><span class="relation">Prior: {{relation}}</span> <br/><span class="relation">Prior: {{relation}}</span>
{% endif %} {% endif %}
</a> </a>
</span> </span>
{% endfor %} {% endfor %}
@@ -168,10 +168,10 @@
</div> </div>
<div> {% if collection.self_review %}
{% if collection.self_review %} <div>
<p> <p>
<a href="{% url 'atlas:add_self_review' cid_user_exam.id case.id %}"><button>Add self review</button></a> <a href="{% url 'atlas:add_self_review' cid_user_exam.id case.id %}"><button type="button">Add self review</button></a>
</p> </p>
{% if self_review %} {% if self_review %}
<h4>Self Feedback</h4> <h4>Self Feedback</h4>
@@ -181,12 +181,12 @@
{% endfor %} {% endfor %}
{% endif %} {% endif %}
{% else %} </div>
<h4>Answer score: {{answer.score}}</h4> {% else %}
Answer feedback: {{answer.feedback|safe}} <h4>Answer score: {{answer.score}}</h4>
<br/> Answer feedback: {{answer.feedback|safe}}
{% endif %} <br/>
</div> {% endif %}
<details><summary class="opacity-50">View questions</summary> <details><summary class="opacity-50">View questions</summary>
{{form.json.errors}} {{form.json.errors}}
@@ -340,7 +340,7 @@
{% for series, prior, relation in series_to_load %} {% for series, prior, relation in series_to_load %}
{{ forloop.counter0 }}: ["{{ series.get_image_url_array_not_json }}"], {{ forloop.counter0 }}: ["{{ series.get_image_url_array_not_json }}"],
{% endfor %} {% endfor %}
} }
$(document).ready(function () { $(document).ready(function () {
+6 -2
View File
@@ -7,7 +7,11 @@
{% block content %} {% block content %}
<div class="container-fluid"> <div class="container-fluid">
Create <a href='{{request.path}}create'>new</a><br/> Create a new <a href='{{request.path}}create'>collection</a> / <a href="{% url 'atlas:user_collections' %}">Collections to view / take</a>
<h2>My Collections</h2>
<details> <details>
<summary> <summary>
<h4>Filter</h4> <h4>Filter</h4>
@@ -18,7 +22,7 @@
<input class="btn btn-primary btn-sm mt-1 mb-1" type="submit" /> <input class="btn btn-primary btn-sm mt-1 mb-1" type="submit" />
</form> </form>
</div> </div>
View my <a href='{% url "atlas:case_view" %}?author={{request.user.id}}'>cases</a>. View my <a href='{% url "atlas:case_view" %}?author={{request.user.id}}'>cases</a>.
</details> </details>
{% render_table table %} {% render_table table %}
</div> </div>
+1
View File
@@ -111,6 +111,7 @@ urlpatterns = [
views.GenericExamViews.exam_users_edit, views.GenericExamViews.exam_users_edit,
name="exam_users_edit", name="exam_users_edit",
), ),
path("exam/<int:pk>/groups", views.ExamGroupsUpdate.as_view(), name="exam_groups_edit"),
path( path(
"collection/<int:exam_id>/case/<int:case_id>/details", "collection/<int:exam_id>/case/<int:case_id>/details",
views.collection_case_details, views.collection_case_details,
+18 -2
View File
@@ -47,6 +47,7 @@ from .forms import (
CidReportAnswerMarkForm, CidReportAnswerMarkForm,
ConditionAutocompleteForm, ConditionAutocompleteForm,
ConditionForm, ConditionForm,
ExamGroupsForm,
FindingForm, FindingForm,
JsonAnswerForm, JsonAnswerForm,
PriorCaseForm, PriorCaseForm,
@@ -144,6 +145,7 @@ from django.forms.models import model_to_dict
from generic.views import ( from generic.views import (
AuthorRequiredMixin, AuthorRequiredMixin,
ExamCloneMixin, ExamCloneMixin,
ExamGroupsUpdateBase,
ExamViews, ExamViews,
SeriesImagesZipViewBase, SeriesImagesZipViewBase,
) )
@@ -2713,6 +2715,15 @@ class CaseCollectionAuthorUpdate(RevisionMixin, AuthorRequiredMixin, UpdateView)
context["collection"] = context["object"] context["collection"] = context["object"]
return context return context
class ExamGroupsUpdate(ExamGroupsUpdateBase):
model = CaseCollection
form_class = ExamGroupsForm
def get_context_data(self, **kwargs):
context = super(ExamGroupsUpdate, self).get_context_data(**kwargs)
context["exam"] = context["object"]
return context
class CaseAuthorUpdate(RevisionMixin, AuthorRequiredMixin, UpdateView): class CaseAuthorUpdate(RevisionMixin, AuthorRequiredMixin, UpdateView):
model = Case model = Case
@@ -2816,8 +2827,12 @@ def collection_reset_answers(request, exam_id: int):
case_details = collection.casedetail_set.all().prefetch_related() case_details = collection.casedetail_set.all().prefetch_related()
# Delete all answers # Delete all answers
cid_answers = case_details.cidreportanswer_set.all() for case in case_details:
user_answers = case_details.userreportanswer_set.all() cid_answers = case.cidreportanswer_set.all()
cid_answers.delete()
user_answers = case.userreportanswer_set.all()
user_answers.delete()
# User statuses # User statuses
@@ -2825,6 +2840,7 @@ def collection_reset_answers(request, exam_id: int):
# CidUserExams # CidUserExams
collection.cid_users.all().delete() collection.cid_users.all().delete()
return HttpResponse("Success")
else: else:
+1 -1
View File
@@ -789,7 +789,7 @@ class ExamOrCollectionGenericBase(models.Model, AuthorMixin):
raise NotImplementedError raise NotImplementedError
def get_cid_user_exams( def get_cid_user_exams(
self, cid_user: Optional["CidUser"] = None, user_user: User = None self, cid_user: Optional["CidUser"] = None, user_user: User | None = None
) -> "CidUserExam": ) -> "CidUserExam":
content_type = ContentType.objects.get_for_model(self) content_type = ContentType.objects.get_for_model(self)
if cid_user is None and user_user is None: if cid_user is None and user_user is None:
+1
View File
@@ -34,6 +34,7 @@ urlpatterns.extend(
name="exam_take_overview_user", name="exam_take_overview_user",
), ),
path("exam/<int:pk>/markers", views.ExamMarkersUpdate.as_view(), name="exam_markers"), path("exam/<int:pk>/markers", views.ExamMarkersUpdate.as_view(), name="exam_markers"),
path("exam/<int:pk>/groups", views.ExamGroupsUpdate.as_view(), name="exam_groups_edit"),
path( path(
"exam/<int:pk>/authors", "exam/<int:pk>/authors",
views.ExamAuthorUpdate.as_view(), views.ExamAuthorUpdate.as_view(),
+1
View File
@@ -51,6 +51,7 @@ urlpatterns = [
"exam/<int:exam_pk>/<int:sk>/mark/review", views.mark_review, name="mark_review" "exam/<int:exam_pk>/<int:sk>/mark/review", views.mark_review, name="mark_review"
), ),
path("exam/<int:pk>/markers", views.ExamMarkersUpdate.as_view(), name="exam_markers"), path("exam/<int:pk>/markers", views.ExamMarkersUpdate.as_view(), name="exam_markers"),
path("exam/<int:pk>/groups", views.ExamGroupsUpdate.as_view(), name="exam_groups_edit"),
path("exam/<int:pk>/authors", views.ExamAuthorUpdate.as_view(), name="exam_authors"), path("exam/<int:pk>/authors", views.ExamAuthorUpdate.as_view(), name="exam_authors"),
path("exam/create", views.ExamCreate.as_view(), name="exam_create"), path("exam/create", views.ExamCreate.as_view(), name="exam_create"),
path("exam/<int:exam_id>/clone", views.ExamClone.as_view(), name="exam_clone"), path("exam/<int:exam_id>/clone", views.ExamClone.as_view(), name="exam_clone"),
+1
View File
@@ -50,6 +50,7 @@ urlpatterns = [
), ),
path("exam/<int:pk>/markers", views.ExamMarkersUpdate.as_view(), name="exam_markers"), path("exam/<int:pk>/markers", views.ExamMarkersUpdate.as_view(), name="exam_markers"),
path("exam/<int:pk>/groups", views.ExamGroupsUpdate.as_view(), name="exam_groups_edit"),
path( path(
"exam/<int:pk>/authors", views.ExamAuthorUpdate.as_view(), name="exam_authors" "exam/<int:pk>/authors", views.ExamAuthorUpdate.as_view(), name="exam_authors"
), ),