continue working on case collections
This commit is contained in:
@@ -3,6 +3,7 @@ from django.contrib.admin import widgets
|
|||||||
from django.forms import (
|
from django.forms import (
|
||||||
BaseInlineFormSet,
|
BaseInlineFormSet,
|
||||||
Form,
|
Form,
|
||||||
|
HiddenInput,
|
||||||
ModelForm,
|
ModelForm,
|
||||||
ModelMultipleChoiceField,
|
ModelMultipleChoiceField,
|
||||||
ModelChoiceField,
|
ModelChoiceField,
|
||||||
@@ -22,6 +23,7 @@ from atlas.models import (
|
|||||||
CidReportAnswer,
|
CidReportAnswer,
|
||||||
Differential,
|
Differential,
|
||||||
Finding,
|
Finding,
|
||||||
|
SelfReview,
|
||||||
Series,
|
Series,
|
||||||
SeriesImage,
|
SeriesImage,
|
||||||
SeriesFinding,
|
SeriesFinding,
|
||||||
@@ -571,3 +573,18 @@ class AddCollectionToCaseForm(Form):
|
|||||||
raise ValidationError("Invalid collection")
|
raise ValidationError("Invalid collection")
|
||||||
|
|
||||||
return collection_set
|
return collection_set
|
||||||
|
|
||||||
|
|
||||||
|
class SelfReviewForm(ModelForm):
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = SelfReview
|
||||||
|
fields = ["user_exam", "case", "comments", "findings", "interpretation"]
|
||||||
|
widgets = {"user_exam": HiddenInput(), "case": HiddenInput()}
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
user_exam_id = kwargs.pop("user_exam_id")
|
||||||
|
case_id = kwargs.pop("case_id")
|
||||||
|
|
||||||
|
ModelForm.__init__(self, *args, **kwargs)
|
||||||
|
super(SelfReviewForm, self).__init__(*args, **kwargs)
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
# Generated by Django 4.1.4 on 2023-07-24 11:42
|
||||||
|
|
||||||
|
import django.core.validators
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('generic', '0008_delete_selfreview'),
|
||||||
|
('atlas', '0006_casecollection_candidates_only_and_more'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='SelfReview',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('comments', models.TextField(blank=True, null=True)),
|
||||||
|
('findings', models.IntegerField(blank=True, null=True, validators=[django.core.validators.MaxValueValidator(5), django.core.validators.MinValueValidator(1)])),
|
||||||
|
('interpretation', models.IntegerField(blank=True, null=True, validators=[django.core.validators.MaxValueValidator(5), django.core.validators.MinValueValidator(1)])),
|
||||||
|
('review_date', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('review_update_date', models.DateTimeField(auto_now=True)),
|
||||||
|
('case', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='atlas.case')),
|
||||||
|
('user_exam', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='generic.ciduserexam')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -578,3 +578,48 @@ class CidReportAnswer(BaseReportAnswer):
|
|||||||
|
|
||||||
class UserReportAnswer(BaseReportAnswer):
|
class UserReportAnswer(BaseReportAnswer):
|
||||||
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
|
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
|
||||||
|
|
||||||
|
|
||||||
|
class SelfReview(models.Model):
|
||||||
|
"""Holds data regarding a users self review / reflection"""
|
||||||
|
|
||||||
|
user_exam = models.ForeignKey(CidUserExam, on_delete=models.CASCADE)
|
||||||
|
|
||||||
|
case = models.ForeignKey(Case, on_delete=models.CASCADE)
|
||||||
|
|
||||||
|
comments = models.TextField(null=True, blank=True)
|
||||||
|
|
||||||
|
findings = models.IntegerField(
|
||||||
|
null=True, blank=True, validators=[MaxValueValidator(5), MinValueValidator(1)]
|
||||||
|
)
|
||||||
|
interpretation = models.IntegerField(
|
||||||
|
null=True, blank=True, validators=[MaxValueValidator(5), MinValueValidator(1)]
|
||||||
|
)
|
||||||
|
|
||||||
|
review_date = models.DateTimeField(auto_now_add=True)
|
||||||
|
review_update_date = models.DateTimeField(auto_now=True)
|
||||||
|
|
||||||
|
def get_absolute_url(self):
|
||||||
|
return reverse(
|
||||||
|
"atlas:collection_take_overview_user", kwargs={"pk": self.user_exam.exam.pk}
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_display_block(self):
|
||||||
|
html = """<div class='self-feedback-block'>
|
||||||
|
Comments: <span class="comment">{comments}</span><br/>
|
||||||
|
|
||||||
|
Findings: <span class="findings">{findings}</span><br/>
|
||||||
|
|
||||||
|
Interpretation: <span class="interpretation">{interpretation}</span><br/>
|
||||||
|
<span class="date">Date: {date}</span><br/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
return format_html(
|
||||||
|
html,
|
||||||
|
comments=self.comments,
|
||||||
|
findings=self.findings,
|
||||||
|
interpretation=self.interpretation,
|
||||||
|
date=self.review_date,
|
||||||
|
)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
{% if collection.publish_results or cid_user_exam.completed %}
|
{% if completed %}
|
||||||
<span class="stamp-white">REVIEW</span>
|
<span class="stamp-white">REVIEW</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
@@ -78,16 +78,30 @@
|
|||||||
<form method="POST" class="post-form">{% csrf_token %}
|
<form method="POST" class="post-form">{% csrf_token %}
|
||||||
{% if collection.collection_type == "REP" %}
|
{% if collection.collection_type == "REP" %}
|
||||||
<div class="form-contents">
|
<div class="form-contents">
|
||||||
<fieldset {% if collection.publish_results or cid_user_exam.completed %}disabled="disabled"{% endif %}>
|
<fieldset {% if completed %}disabled="disabled"{% endif %}>
|
||||||
{{form}}
|
{{form}}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</div>
|
</div>
|
||||||
<p>
|
<p>
|
||||||
{% if collection.publish_results %}
|
{% if completed %}
|
||||||
<h4>Answer score: {{answer.score}}</h4>
|
<h4>Answer score: {{answer.score}}</h4>
|
||||||
Answer feedback: {{answer.feedback|safe}}
|
Answer feedback: {{answer.feedback|safe}}
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
{% if self_review %}
|
||||||
|
<h4>Self Feedback</h4>
|
||||||
|
|
||||||
|
{% for review in self_review %}
|
||||||
|
{{review.get_display_block}}
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if previous %}
|
{% if previous %}
|
||||||
<button type="submit" name="previous" class="save btn btn-default">Previous</button>
|
<button type="submit" name="previous" class="save btn btn-default">Previous</button>
|
||||||
@@ -103,6 +117,10 @@
|
|||||||
<br />
|
<br />
|
||||||
<button type="submit" name="finish" class="save btn btn-default">Overview</button>
|
<button type="submit" name="finish" class="save btn btn-default">Overview</button>
|
||||||
<button type="submit" id="goto-button" value="test" name="goto" class="hide">goto</button>
|
<button type="submit" id="goto-button" value="test" name="goto" class="hide">goto</button>
|
||||||
|
{% if collection.publish_results or cid_user_exam.completed %}
|
||||||
|
<a href="{% url 'atlas:add_self_review' cid_user_exam.id case.id %}">Add self review</a>
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
</form>
|
</form>
|
||||||
<style>
|
<style>
|
||||||
label {
|
label {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<div class="floating-header">
|
<div class="floating-header">
|
||||||
<a href="{% url 'atlas:exam_update' collection.id %}" title="Edit the Collection">Edit</a>
|
<a href="{% url 'atlas:exam_update' collection.id %}" title="Edit the Collection">Edit</a>
|
||||||
\ <a href="{% url 'atlas:exam_deleted' collection.id %}" title="Delete the Collection">Delete</a>
|
\ <a href="{% url 'atlas:exam_deleted' collection.id %}" title="Delete the Collection">Delete</a>
|
||||||
{% comment %} \ <a href="{% url 'atlas:collection_clone' collection.id %}" title="Clone the Collection">Clone</a> {% endcomment %}
|
\ <a href="{% url 'atlas:exam_clone' collection.id %}" title="Clone the Collection">Clone</a>
|
||||||
{% if request.user.is_superuser %}
|
{% if request.user.is_superuser %}
|
||||||
\ <a href="{% url 'admin:atlas_casecollection_change' collection.id %}" title="Edit the Collection using the admin interface">Admin Edit</a>
|
\ <a href="{% url 'admin:atlas_casecollection_change' collection.id %}" title="Edit the Collection using the admin interface">Admin Edit</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -3,10 +3,26 @@
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
<h2>Collection: {{exam.name}}</h2>
|
<h2>Collection: {{exam.name}}</h2>
|
||||||
|
|
||||||
<ul>
|
{% comment %} <ul>
|
||||||
{% for case in collection.cases.all %}
|
{% for case in collection.cases.all %}
|
||||||
<li><a href="{% url 'atlas:collection_case_view_review' pk=collection.id case_number=forloop.counter0 %}">Case {{forloop.counter}}</a></li>
|
<li><a href="{% url 'atlas:collection_case_view_take_user' pk=collection.id case_number=forloop.counter0 %}">Case {{forloop.counter}}</a></li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul> {% endcomment %}
|
||||||
|
|
||||||
|
User: {{request.user}}<br/>
|
||||||
|
|
||||||
|
{% if cid_exam %}
|
||||||
|
Started: {{cid_exam.start_time}} <br/>
|
||||||
|
{% if cid_exam.completed %}
|
||||||
|
Ended: {{cid_exam.end_time}} <br/>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<a href="{% url 'atlas:collection_case_view_take_user' pk=collection.pk case_number=0 %}">
|
||||||
|
{% if cid_exam.completed %}
|
||||||
|
<button>Review</button>
|
||||||
|
{% else %}
|
||||||
|
<button>Start</button>
|
||||||
|
{% endif %}
|
||||||
|
</a>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
<div class="sba-finish-list">
|
<div class="sba-finish-list">
|
||||||
<ul>
|
<ul>
|
||||||
{% for question, answer in question_answer_tuples %}
|
{% for question, answer in question_answer_tuples %}
|
||||||
<li> <span {% if not answer %}class="unanswered"{% endif %}>
|
<li> <span {% if not collection.review_only and not answer %}class="unanswered"{% endif %}>
|
||||||
<a href="
|
<a href="
|
||||||
{% if cid is not None %}
|
{% if cid is not None %}
|
||||||
{% url 'atlas:collection_case_view_take' pk=collection.id case_number=forloop.counter0 cid=cid passcode=passcode %}
|
{% url 'atlas:collection_case_view_take' pk=collection.id case_number=forloop.counter0 cid=cid passcode=passcode %}
|
||||||
@@ -27,11 +27,13 @@
|
|||||||
Case: {{forloop.counter}}
|
Case: {{forloop.counter}}
|
||||||
</a>
|
</a>
|
||||||
<br/>
|
<br/>
|
||||||
|
{% if not collection.review_only %}
|
||||||
{% if not answer %}
|
{% if not answer %}
|
||||||
No answer
|
No answer
|
||||||
{% else %}
|
{% else %}
|
||||||
{{answer.answer}}
|
{{answer.answer}}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
|
||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h2>Add Self Review</h2>
|
||||||
|
<div class="alert alert-info" role="alert">
|
||||||
|
Adding self feedback for {{user_exam.exam}}/{{case}}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<form action="" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ form.non_field_errors }}
|
||||||
|
|
||||||
|
{{ form.as_p }}
|
||||||
|
{% comment %} <div class="fieldWrapper">
|
||||||
|
{{ form.content_type.errors }}
|
||||||
|
{{ form.content_type }}
|
||||||
|
</div>
|
||||||
|
<div class="fieldWrapper">
|
||||||
|
{{ form.object_id.errors }}
|
||||||
|
{{ form.object_id }}
|
||||||
|
</div>
|
||||||
|
<div class="fieldWrapper">
|
||||||
|
{{ form.note_type.errors }}
|
||||||
|
<label for="{{ form.note_type.id_for_label }}">Note type</label>
|
||||||
|
{{ form.note_type }}
|
||||||
|
</div>
|
||||||
|
<div class="fieldWrapper">
|
||||||
|
{{ form.note.errors }}
|
||||||
|
<label for="{{ form.note.id_for_label }}">Additional information</label><br/>
|
||||||
|
{{ form.note }}
|
||||||
|
</div> {% endcomment %}
|
||||||
|
<input type="submit" value="Submit">
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
||||||
@@ -14,6 +14,11 @@ urlpatterns = [
|
|||||||
RedirectView.as_view(pattern_name="atlas:case_create", permanent=False),
|
RedirectView.as_view(pattern_name="atlas:case_create", permanent=False),
|
||||||
name="create",
|
name="create",
|
||||||
),
|
),
|
||||||
|
path(
|
||||||
|
"add_self_review/<int:user_exam_id>/<int:case_id>",
|
||||||
|
views.AddSelfReview.as_view(),
|
||||||
|
name="add_self_review",
|
||||||
|
),
|
||||||
path("author/<int:pk>/", views.author_detail, name="author_detail"),
|
path("author/<int:pk>/", views.author_detail, name="author_detail"),
|
||||||
path("author/", views.author_list, name="author_list"),
|
path("author/", views.author_list, name="author_list"),
|
||||||
path("case/", views.CaseView.as_view(), name="case_view"),
|
path("case/", views.CaseView.as_view(), name="case_view"),
|
||||||
@@ -23,6 +28,7 @@ urlpatterns = [
|
|||||||
views.CaseCollectionCreate.as_view(),
|
views.CaseCollectionCreate.as_view(),
|
||||||
name="exam_create",
|
name="exam_create",
|
||||||
),
|
),
|
||||||
|
path("collection/<int:exam_id>/clone", views.CollectionClone.as_view(), name="exam_clone"),
|
||||||
path(
|
path(
|
||||||
"collection/<int:pk>/delete",
|
"collection/<int:pk>/delete",
|
||||||
views.CaseCollectionDelete.as_view(),
|
views.CaseCollectionDelete.as_view(),
|
||||||
|
|||||||
+78
-9
@@ -27,7 +27,7 @@ from django.urls import reverse_lazy, reverse
|
|||||||
from django.http import Http404, JsonResponse
|
from django.http import Http404, JsonResponse
|
||||||
from django.http import HttpResponseRedirect, HttpResponse
|
from django.http import HttpResponseRedirect, HttpResponse
|
||||||
|
|
||||||
from generic.models import CidUser
|
from generic.models import CidUser, CidUserExam
|
||||||
|
|
||||||
from .forms import (
|
from .forms import (
|
||||||
AddCollectionToCaseForm,
|
AddCollectionToCaseForm,
|
||||||
@@ -38,6 +38,7 @@ from .forms import (
|
|||||||
CidReportAnswerMarkForm,
|
CidReportAnswerMarkForm,
|
||||||
ConditionForm,
|
ConditionForm,
|
||||||
FindingForm,
|
FindingForm,
|
||||||
|
SelfReviewForm,
|
||||||
SeriesForm,
|
SeriesForm,
|
||||||
SeriesImageFormSet,
|
SeriesImageFormSet,
|
||||||
SeriesFormSet,
|
SeriesFormSet,
|
||||||
@@ -54,6 +55,7 @@ from .models import (
|
|||||||
Condition,
|
Condition,
|
||||||
PathologicalProcess,
|
PathologicalProcess,
|
||||||
Presentation,
|
Presentation,
|
||||||
|
SelfReview,
|
||||||
Series,
|
Series,
|
||||||
Examination,
|
Examination,
|
||||||
Finding,
|
Finding,
|
||||||
@@ -1114,7 +1116,7 @@ def collection_take_start(request, pk):
|
|||||||
valid_user = (collection.check_logged_in_user(request),)
|
valid_user = (collection.check_logged_in_user(request),)
|
||||||
|
|
||||||
cid_exam = None
|
cid_exam = None
|
||||||
if valid_user:
|
if collection.collection_type == "REV" or valid_user:
|
||||||
cid_exam = collection.get_cid_user_exams(user_user=request.user).first()
|
cid_exam = collection.get_cid_user_exams(user_user=request.user).first()
|
||||||
|
|
||||||
template_variables = {
|
template_variables = {
|
||||||
@@ -1372,14 +1374,13 @@ def collection_case_view_take(
|
|||||||
collection = get_object_or_404(CaseCollection, pk=pk)
|
collection = get_object_or_404(CaseCollection, pk=pk)
|
||||||
|
|
||||||
form = None
|
form = None
|
||||||
answer: CidReportAnswer | UserReportAnswer
|
answer: None | CidReportAnswer | UserReportAnswer = None
|
||||||
|
|
||||||
collection.check_user_can_take(cid, passcode, request)
|
collection.check_user_can_take(cid, passcode, request)
|
||||||
|
|
||||||
cases = collection.cases.all().order_by("casedetail__sort_order").prefetch_related()
|
cases = collection.cases.all().order_by("casedetail__sort_order").prefetch_related()
|
||||||
case = cases[case_number]
|
case = cases[case_number]
|
||||||
|
|
||||||
if not collection.review_only():
|
|
||||||
cid_user_exam = collection.get_or_create_cid_user_exam(
|
cid_user_exam = collection.get_or_create_cid_user_exam(
|
||||||
cid=cid, user_user=request.user
|
cid=cid, user_user=request.user
|
||||||
)
|
)
|
||||||
@@ -1388,6 +1389,9 @@ def collection_case_view_take(
|
|||||||
cid_user_exam.start_time = timezone.now()
|
cid_user_exam.start_time = timezone.now()
|
||||||
cid_user_exam.save()
|
cid_user_exam.save()
|
||||||
|
|
||||||
|
|
||||||
|
if not collection.review_only():
|
||||||
|
|
||||||
if collection.collection_type == "REP":
|
if collection.collection_type == "REP":
|
||||||
case_detail = CaseDetail.objects.get(case=case, collection=collection)
|
case_detail = CaseDetail.objects.get(case=case, collection=collection)
|
||||||
|
|
||||||
@@ -1429,10 +1433,6 @@ def collection_case_view_take(
|
|||||||
redirect_url = "atlas:collection_case_view_take_user"
|
redirect_url = "atlas:collection_case_view_take_user"
|
||||||
overview_url = "atlas:collection_take_overview_user"
|
overview_url = "atlas:collection_take_overview_user"
|
||||||
|
|
||||||
else:
|
|
||||||
kwargs = {"pk": pk}
|
|
||||||
redirect_url = "atlas:collection_case_view_take"
|
|
||||||
|
|
||||||
if "next" in request.POST:
|
if "next" in request.POST:
|
||||||
return redirect(redirect_url, case_number=case_number + 1, **kwargs)
|
return redirect(redirect_url, case_number=case_number + 1, **kwargs)
|
||||||
elif "previous" in request.POST:
|
elif "previous" in request.POST:
|
||||||
@@ -1457,18 +1457,23 @@ def collection_case_view_take(
|
|||||||
|
|
||||||
# Set what details a user is / is not able to view when taking the case
|
# Set what details a user is / is not able to view when taking the case
|
||||||
# this can be configured via the collection edit menu
|
# this can be configured via the collection edit menu
|
||||||
if collection.publish_results:
|
if collection.publish_results or cid_user_exam.completed:
|
||||||
|
completed = True
|
||||||
show_title = collection.show_title_post
|
show_title = collection.show_title_post
|
||||||
show_history = collection.show_history_post
|
show_history = collection.show_history_post
|
||||||
show_description = collection.show_description_post
|
show_description = collection.show_description_post
|
||||||
show_discussion = collection.show_discussion_post
|
show_discussion = collection.show_discussion_post
|
||||||
show_report = collection.show_report_post
|
show_report = collection.show_report_post
|
||||||
|
|
||||||
|
self_review = cid_user_exam.selfreview_set.filter(case=case)
|
||||||
else:
|
else:
|
||||||
|
completed = False
|
||||||
show_title = collection.show_title_pre
|
show_title = collection.show_title_pre
|
||||||
show_history = collection.show_history_pre
|
show_history = collection.show_history_pre
|
||||||
show_description = collection.show_description_pre
|
show_description = collection.show_description_pre
|
||||||
show_discussion = collection.show_discussion_pre
|
show_discussion = collection.show_discussion_pre
|
||||||
show_report = collection.show_report_pre
|
show_report = collection.show_report_pre
|
||||||
|
self_review = []
|
||||||
|
|
||||||
return render(
|
return render(
|
||||||
request,
|
request,
|
||||||
@@ -1490,6 +1495,8 @@ def collection_case_view_take(
|
|||||||
"show_discussion": show_discussion,
|
"show_discussion": show_discussion,
|
||||||
"show_report": show_report,
|
"show_report": show_report,
|
||||||
"cid_user_exam": cid_user_exam,
|
"cid_user_exam": cid_user_exam,
|
||||||
|
"completed": completed,
|
||||||
|
"self_review": self_review,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1735,3 +1742,65 @@ def collection_scores_cid(request, pk):
|
|||||||
GenericExamViews = ExamViews(
|
GenericExamViews = ExamViews(
|
||||||
CaseCollection, Case, None, CidReportAnswer, "atlas", "casecollection"
|
CaseCollection, Case, None, CidReportAnswer, "atlas", "casecollection"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
class CollectionCloneMixin:
|
||||||
|
def get_initial(self):
|
||||||
|
old_object = get_object_or_404(self.model, pk=self.kwargs["exam_id"])
|
||||||
|
initial_data = model_to_dict(old_object, exclude=["id"])
|
||||||
|
|
||||||
|
# We manually transfer the forign keys / m2m relationships
|
||||||
|
questions = old_object.cases.all().values_list("id", flat=True)
|
||||||
|
authors = old_object.author.all().values_list("id", flat=True)
|
||||||
|
|
||||||
|
self.cases = list(questions)
|
||||||
|
self.author = list(authors)
|
||||||
|
|
||||||
|
return initial_data
|
||||||
|
|
||||||
|
def form_valid(self, form):
|
||||||
|
object = form.save()
|
||||||
|
# Reapply these otherwise they get lost?
|
||||||
|
object.cases.set(self.cases)
|
||||||
|
object.author.set(self.author)
|
||||||
|
object.save()
|
||||||
|
return HttpResponseRedirect(object.get_absolute_url())
|
||||||
|
|
||||||
|
class CollectionClone(CollectionCloneMixin, CaseCollectionCreate):
|
||||||
|
"""Clone exam view"""
|
||||||
|
|
||||||
|
class AddSelfReview(CreateView):
|
||||||
|
model = SelfReview
|
||||||
|
form_class = SelfReviewForm
|
||||||
|
|
||||||
|
# fields = ("author", "note_type", "note")
|
||||||
|
|
||||||
|
def get_form_kwargs(self):
|
||||||
|
kwargs = super(AddSelfReview, 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
|
||||||
|
#kwargs.update({"user": self.request.user})
|
||||||
|
return kwargs
|
||||||
|
|
||||||
|
def get_initial(self):
|
||||||
|
user_exam_id = self.kwargs["user_exam_id"]
|
||||||
|
case_id = self.kwargs["case_id"]
|
||||||
|
|
||||||
|
self.user_exam = get_object_or_404(CidUserExam, pk=user_exam_id)
|
||||||
|
self.case = get_object_or_404(Case, pk=case_id)
|
||||||
|
return {"user_exam": user_exam_id, "case": case_id}
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
# This can also be accessed via view.**** in the template
|
||||||
|
context = super(AddSelfReview, self).get_context_data(**kwargs)
|
||||||
|
context["user_exam"] = self.user_exam
|
||||||
|
context["case"] = self.case
|
||||||
|
return context
|
||||||
|
|
||||||
|
# def form_valid(self, form):
|
||||||
|
# model = form.save(commit=False)
|
||||||
|
#
|
||||||
|
# model.save()
|
||||||
|
#
|
||||||
|
# response = super().form_valid(form)
|
||||||
|
#
|
||||||
|
# return response
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
# Generated by Django 4.1.4 on 2023-07-24 11:15
|
||||||
|
|
||||||
|
import django.core.validators
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('atlas', '0006_casecollection_candidates_only_and_more'),
|
||||||
|
('generic', '0006_alter_ciduserexam_completed'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='SelfReview',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('comments', models.TextField(blank=True, null=True)),
|
||||||
|
('findings', models.IntegerField(blank=True, null=True, validators=[django.core.validators.MaxValueValidator(5), django.core.validators.MinValueValidator(1)])),
|
||||||
|
('interpretation', models.IntegerField(blank=True, null=True, validators=[django.core.validators.MaxValueValidator(5), django.core.validators.MinValueValidator(1)])),
|
||||||
|
('review_date', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('review_update_date', models.DateTimeField(auto_now=True)),
|
||||||
|
('case', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='atlas.case')),
|
||||||
|
('user_exam', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='generic.ciduserexam')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
# Generated by Django 4.1.4 on 2023-07-24 11:42
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('generic', '0007_selfreview'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.DeleteModel(
|
||||||
|
name='SelfReview',
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -6,6 +6,7 @@ from django.contrib.auth.mixins import LoginRequiredMixin
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
from django.http import Http404, HttpRequest
|
from django.http import Http404, HttpRequest
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
from django.core.validators import MaxValueValidator, MinValueValidator
|
||||||
from smtplib import SMTPException
|
from smtplib import SMTPException
|
||||||
|
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
@@ -1315,3 +1316,4 @@ def create_user_profile(sender, instance, created, **kwargs):
|
|||||||
@receiver(post_save, sender=User)
|
@receiver(post_save, sender=User)
|
||||||
def save_user_profile(sender, instance, **kwargs):
|
def save_user_profile(sender, instance, **kwargs):
|
||||||
instance.userprofile.save()
|
instance.userprofile.save()
|
||||||
|
|
||||||
|
|||||||
@@ -1000,3 +1000,12 @@ h1, h2, h3, h4, h5, h6 {
|
|||||||
text-shadow: 0 0 2px white;
|
text-shadow: 0 0 2px white;
|
||||||
box-shadow: 0 0 2px white;
|
box-shadow: 0 0 2px white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.self-feedback-block {
|
||||||
|
border: gray 1px dashed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.self-feedback-block.data {
|
||||||
|
opacity: 60%;
|
||||||
|
font-size: small;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user