Merge branch 'master' of ssh://git.xkjq.uk:30001/ross/rad

This commit is contained in:
Ross
2021-05-26 10:11:16 +01:00
7 changed files with 87 additions and 17 deletions
+4
View File
@@ -481,4 +481,8 @@ td.user-answer-score-2::after {
.proposed-answer { .proposed-answer {
color: darkblue color: darkblue
}
.notes .complete {
color: darkslategray;
} }
+4 -1
View File
@@ -126,4 +126,7 @@ class QuestionNote(models.Model):
return "{} [{}] {} / {}".format(self.author, self.created_on, self.note_type, self.note) return "{} [{}] {} / {}".format(self.author, self.created_on, self.note_type, self.note)
def get_absolute_url(self): def get_absolute_url(self):
return "/" return "/"
def get_object_url(self):
return self.question.get_absolute_url()
+2
View File
@@ -57,9 +57,11 @@ urlpatterns = [
path("exam/submit", views.exam_submit, name="global_exam_answers_submit"), path("exam/submit", views.exam_submit, name="global_exam_answers_submit"),
#path('', include('generic.urls')), #path('', include('generic.urls')),
path("feedback/<str:question_type>/<int:pk>", views.AddQuestionNote.as_view(), name="feedback_create"), path("feedback/<str:question_type>/<int:pk>", views.AddQuestionNote.as_view(), name="feedback_create"),
path("feedback/note/<int:pk>/complete", views.feedback_mark_complete, name="feedback_mark_complete"),
#path("feedback/", views.AddQuestionNote.as_view(), name="feedback"), #path("feedback/", views.AddQuestionNote.as_view(), name="feedback"),
path("feedback/answer", views.answer_suggestion_submit, name="answer_suggestion_submit"), path("feedback/answer", views.answer_suggestion_submit, name="answer_suggestion_submit"),
path("feedback/answer/confirm", views.answer_suggestion_confirm, name="answer_suggestion_confirm"), path("feedback/answer/confirm", views.answer_suggestion_confirm, name="answer_suggestion_confirm"),
path("feedback/view", views.view_feedback, name="view_feedback"),
path('api/', include(router.urls)), path('api/', include(router.urls)),
+49 -12
View File
@@ -1,3 +1,4 @@
from django.core.exceptions import PermissionDenied
from django.shortcuts import render, get_object_or_404, redirect from django.shortcuts import render, get_object_or_404, redirect
from django.views.decorators.csrf import csrf_exempt from django.views.decorators.csrf import csrf_exempt
from django import forms from django import forms
@@ -23,7 +24,7 @@ from django.http import Http404, JsonResponse
from django.http import HttpResponseRedirect, HttpResponse from django.http import HttpResponseRedirect, HttpResponse
from physics.models import CidUserAnswer as PhysicsCidUserAnswer from physics.models import CidUserAnswer as PhysicsCidUserAnswer, Question
from physics.models import Exam as PhysicsExam from physics.models import Exam as PhysicsExam
from anatomy.models import CidUserAnswer as AnatomyCidUserAnswer from anatomy.models import CidUserAnswer as AnatomyCidUserAnswer
@@ -48,6 +49,9 @@ from generic.models import QuestionNote
import json import json
def feedback_checker(user):
return user.groups.filter(name="feedback_checker").exists()
@login_required @login_required
def profile(request): def profile(request):
@@ -162,6 +166,22 @@ def feedback_create(request, question_type, pk):
return JsonResponse({"success": False, "error": "Invalid exam type"}) return JsonResponse({"success": False, "error": "Invalid exam type"})
def get_question_and_content_type(pk, 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()
return question, content_type
class AddQuestionNote(CreateView): class AddQuestionNote(CreateView):
model = QuestionNote model = QuestionNote
form_class = QuestionNoteForm form_class = QuestionNoteForm
@@ -178,22 +198,24 @@ class AddQuestionNote(CreateView):
def get_initial(self): def get_initial(self):
pk = self.kwargs["pk"] pk = self.kwargs["pk"]
question_type = self.kwargs["question_type"] question_type = self.kwargs["question_type"]
if question_type == "rapid":
question = Rapid question, content_type = get_question_and_content_type(pk, question_type)
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) get_object_or_404(question, pk=pk)
return { "content_type" : content_type, return { "content_type" : content_type,
"object_id" : pk } "object_id" : pk }
@login_required
def feedback_mark_complete(request, pk):
q = get_object_or_404(QuestionNote, pk=pk)
if request.user not in q.question.author.all() and not request.user.groups.filter(name="feedback_checker").exists():
raise PermissionDenied()
q.complete = True
q.save()
return redirect(q.get_object_url())
@csrf_exempt @csrf_exempt
def answer_suggestion_submit(request): def answer_suggestion_submit(request):
if request.is_ajax and request.method == "POST": if request.is_ajax and request.method == "POST":
@@ -247,3 +269,18 @@ def answer_suggestion_confirm(request):
answer.status = status answer.status = status
answer.save() answer.save()
return JsonResponse({"success": True, "error": "Answer changed"}) return JsonResponse({"success": True, "error": "Answer changed"})
@login_required
@user_passes_test(feedback_checker)
def view_feedback(request):
# exam = get_object_or_404(Exam, pk=pk)
feedback_notes = QuestionNote.objects.filter(complete=False)
return render(
request,
"view_feedback.html",
{
"notes": feedback_notes,
},
)
@@ -37,6 +37,8 @@
</p> </p>
</div> </div>
<div> <div>
{% if view_feedback %}
Notes: Notes:
<ul> <ul>
{% for note in question.rapid_notes.all %} {% for note in question.rapid_notes.all %}
@@ -46,13 +48,17 @@
{% endfor %} {% endfor %}
</ul> </ul>
Anon Notes: Anon Notes:
<ul> <ul class="notes">
{% for note in question.anon_notes.all %} {% for note in question.anon_notes.all %}
<li> <li {% if note.complete %}class='complete' {% endif %}>
{{ note.created_on }} by {{ note.author }}: {{ note.note }} {{ note.created_on }} by {{ note.author }}: {{note.note_type}} / {{ note.note }}
{% if not note.complete %}
(<a href="{% url 'feedback_mark_complete' pk=note.pk %}">Mark complete</a>)
{% endif %}
</li> </li>
{% endfor %} {% endfor %}
</ul> </ul>
{% endif %}
<div id="single-dicom-viewer" class="dicom-viewer" data-images="{{ question.GetImageUrls }}" data-annotations=''></div> <div id="single-dicom-viewer" class="dicom-viewer" data-images="{{ question.GetImageUrls }}" data-annotations=''></div>
</div> </div>
+5 -1
View File
@@ -101,9 +101,13 @@ def question_detail(request, pk):
# if request.user not in rapid.author.all(): # if request.user not in rapid.author.all():
# raise PermissionDenied # raise PermissionDenied
view_feedback = False
if request.user.groups.filter(name="rapid_checker").exists() or request.user.groups.filter(name="feedback_checker").exists() or request.user in rapid.author.all():
view_feedback = True
# logging.debug(rapid.rapid_notes.first()) # logging.debug(rapid.rapid_notes.first())
# logging.debug(rapid.subspecialty.first().name.all()) # logging.debug(rapid.subspecialty.first().name.all())
return render(request, "rapids/question_detail.html", {"question": rapid}) return render(request, "rapids/question_detail.html", {"question": rapid, "view_feedback" : view_feedback})
@login_required @login_required
+14
View File
@@ -0,0 +1,14 @@
{% extends 'base.html' %}
{% block content %}
<div class="anatomy">
<h1>Feedback</h1>
Displays a list of feedback reports yet to be acted upon
<ul>
{% for note in notes %}
<li><a href="{{ note.get_object_url }}">{{note.content_type }}</a>: {{note.note_type}} / {{note.note}} </li>
{% endfor %}
</ul>
</div>
{% endblock %}