fix a few missing things
This commit is contained in:
@@ -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
@@ -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):
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|
||||||
|
|||||||
@@ -68,17 +68,17 @@
|
|||||||
</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>
|
||||||
@@ -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}}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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:
|
||||||
|
|||||||
@@ -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(),
|
||||||
|
|||||||
@@ -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"),
|
||||||
|
|||||||
@@ -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"
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user