From c2185f73a643987d6bffd202a207be6126dae9b5 Mon Sep 17 00:00:00 2001 From: Ross Date: Mon, 12 Aug 2024 11:58:28 +0100 Subject: [PATCH] add a redirct view mixin --- anatomy/views.py | 21 +-- generic/models.py | 10 ++ generic/views.py | 23 +++- longs/templates/longs/long_display_block.html | 123 ++++++++++-------- longs/templates/longs/question_detail.html | 2 +- longs/views.py | 32 +++-- rapids/views.py | 9 +- sbas/views.py | 12 +- 8 files changed, 126 insertions(+), 106 deletions(-) diff --git a/anatomy/views.py b/anatomy/views.py index 61903d88..c15ab7ec 100644 --- a/anatomy/views.py +++ b/anatomy/views.py @@ -52,7 +52,7 @@ from .models import ( # IncorrectAnswers, ) from generic.models import CidUser, Examination -from generic.views import AuthorRequiredMixin, ExamCloneMixin, ExamCreateBase, ExamDeleteBase, ExamGroupsUpdateBase, ExamUpdateBase, ExamViews, GenericViewBase +from generic.views import AuthorRequiredMixin, ExamCloneMixin, ExamCreateBase, ExamDeleteBase, ExamGroupsUpdateBase, ExamUpdateBase, ExamViews, GenericViewBase, UpdateQuestionMixin from reversion.views import RevisionMixin from .decorators import user_is_author_or_anatomy_checker @@ -598,27 +598,10 @@ class AnatomyQuestionAnswerUpdate(RevisionMixin, AuthorOrCheckerRequiredMixin, U return super().form_invalid(form) # class AnatomyQuestionUpdate(LoginRequiredMixin, AuthorOrCheckerRequiredMixin, -class AnatomyQuestionUpdate(RevisionMixin, AuthorOrCheckerRequiredMixin, UpdateView): +class AnatomyQuestionUpdate(UpdateQuestionMixin,AuthorOrCheckerRequiredMixin): model = AnatomyQuestion form_class = AnatomyQuestionForm - def get_form_kwargs(self): - kwargs = super(AnatomyQuestionUpdate, self).get_form_kwargs() - kwargs.update({"user": self.request.user}) - return kwargs - - def get_context_data(self, **kwargs): - context = super(AnatomyQuestionUpdate, self).get_context_data(**kwargs) - #if self.request.POST: - # context["answer_formset"] = AnswerUpdateFormSet( - # self.request.POST, self.request.FILES, instance=self.object - # ) - # context["answer_formset"].full_clean() - #else: - # context["answer_formset"] = AnswerUpdateFormSet(instance=self.object) - context["question"] = context["object"] - return context - def form_valid(self, form): self.object = form.save(commit=False) self.object.save() diff --git a/generic/models.py b/generic/models.py index 73b10ce5..2420ad2e 100644 --- a/generic/models.py +++ b/generic/models.py @@ -186,6 +186,16 @@ class QuestionBase(models.Model, AuthorMixin, QuestionMixin): """If this makes sense in the question/answer context override""" return None + def can_edit(self, user: User) -> bool: + """Returns True if the user can edit the question""" + if user.is_superuser: + return True + + if user in self.get_author_objects(): + return True + + return False + class SeriesImageBase(models.Model): """ diff --git a/generic/views.py b/generic/views.py index e49e1009..95fdf81f 100644 --- a/generic/views.py +++ b/generic/views.py @@ -1515,6 +1515,8 @@ class ExamViews(View, LoginRequiredMixin): ): view_feedback = True + can_edit = question.can_edit(request.user) + return render( request, "{}/question_detail.html".format(self.app_name), @@ -1526,6 +1528,7 @@ class ExamViews(View, LoginRequiredMixin): "exam_length": exam_length, "pos": pos, "view_feedback": view_feedback, + "can_edit": can_edit, }, ) @@ -3512,4 +3515,22 @@ class ExamGroupsUpdateBase( def get_form_kwargs(self): kwargs = super(ExamGroupsUpdateBase, self).get_form_kwargs() kwargs.update({"user": self.request.user}) - return kwargs \ No newline at end of file + return kwargs + +class RedirectMixin(): + def get_success_url(self) -> str: + if "redirect" in self.request.GET: + return self.request.GET["redirect"] + return super().get_success_url() + +class UpdateQuestionMixin(RedirectMixin, RevisionMixin, UpdateView): + + def get_form_kwargs(self): + kwargs = super().get_form_kwargs() + kwargs.update({"user": self.request.user}) + return kwargs + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context["question"] = context["object"] + return context diff --git a/longs/templates/longs/long_display_block.html b/longs/templates/longs/long_display_block.html index 7d62af16..f6c21851 100755 --- a/longs/templates/longs/long_display_block.html +++ b/longs/templates/longs/long_display_block.html @@ -11,77 +11,86 @@
Series: {% for series in question.series.all %} - - - Series {{ forloop.counter }}: - - {{series.get_block}} - + + + Series {{ forloop.counter }}: + + {{series.get_block}} + -
- - Popup +
+ + Popup +
-
{% endfor %} Add new series

Author(s): {% for author in question.author.all %} {{author}}, {% endfor %}

+ href="{% url 'longs:author_detail' pk=author.pk %}">{{author}}, {% endfor %}

Checked by: {% for verified in question.verified.all %} {{verified}}, {% endfor %}

+ href="{% url 'longs:verified_detail' pk=verified.pk %}">{{verified}}, {% endfor %}

{% comment %}

Scrapped: {{ question.scrapped }} (toggle) {% endcomment %} -

-

Feedback: +

+

Feedback:

{{ question.feedback | safe}}
+

+
+ + Model answers + + + {% if not question.model_differential_diagnosis and not question.model_interpretation and not question.model_management and not question.model_observations and not question.model_principle_diagnosis %} +
No model answers. + {% if can_edit %} + Add some nowr. + {% endif %} +
+ {% endif %} + +

Observations: +

{{ question.model_observations|default:"None" }}

+

Interpretation: +

{{ question.model_interpretation|default:"None" }}
+

+

Principle Diagnosis: +

{{ question.model_principle_diagnosis|default:"None" }}
+

+

Differential Diagnosis: +

{{ question.model_differential_diagnosis|default:"None" }}
+

+

Managment: +

{{ question.model_management|default:"None" }}
+

+
+ +

- - Model answers - -

Observations: -

{{ question.model_observations }}
-

-

Interpretation: -

{{ question.model_interpretation }}
-

-

Principle Diagnosis: -

{{ question.model_principle_diagnosis }}
-

-

Differential Diagnosis: -

{{ question.model_differential_diagnosis }}
-

-

Managment: -

{{ question.model_management }}
-

-
- -

-

- Mark Scheme: + Mark Scheme:
{{ question.mark_scheme | safe}}
-
-

-
-

-
- Exam(s): {% for exam in question.exams.all %} + +

+
+

+
+ Exam(s): {% for exam in question.exams.all %} {{ exam }}, - {% endfor %} -
-
- {% include 'question_notes.html' %} + {% endfor %} +
+
+ {% include 'question_notes.html' %} -
-
- JSON creation time: {{question.json_creation_time}} ({{question.json_creation_time|date:"c"}}), - JSON creation id: {{question.question_json_id}} - {% if question.recreate_json %}[JSON out of date]{% endif %} -
- JSON - JSON (unbased) - Refresh JSON cache \ No newline at end of file +
+
+ JSON creation time: {{question.json_creation_time}} ({{question.json_creation_time|date:"c"}}), + JSON creation id: {{question.question_json_id}} + {% if question.recreate_json %}[JSON out of date]{% endif %} +
+JSON +JSON (unbased) +Refresh JSON cache \ No newline at end of file diff --git a/longs/templates/longs/question_detail.html b/longs/templates/longs/question_detail.html index d57a8990..b14421d6 100755 --- a/longs/templates/longs/question_detail.html +++ b/longs/templates/longs/question_detail.html @@ -5,7 +5,7 @@
-Edit +Edit Clone Delete Add Note diff --git a/longs/views.py b/longs/views.py index 77044d1f..af083b0e 100755 --- a/longs/views.py +++ b/longs/views.py @@ -85,7 +85,9 @@ from generic.views import ( ExamGroupsUpdateBase, ExamUpdateBase, ExamViews, + RedirectMixin, SeriesImagesZipViewBase, + UpdateQuestionMixin, ) from reversion.views import RevisionMixin import reversion @@ -155,7 +157,10 @@ def question_detail(request, pk): # raise PermissionDenied # logging.debug(long.subspecialty.first().name.all()) - return render(request, "longs/question_detail.html", {"question": long}) + can_edit = long.can_edit(request.user) + return render( + request, "longs/question_detail.html", {"question": long, "can_edit": can_edit} + ) @login_required @@ -500,7 +505,7 @@ class LongCreate(LongCreateBase): class LongUpdate( - RevisionMixin, LoginRequiredMixin, AuthorOrCheckerRequiredMixin, UpdateView + UpdateQuestionMixin,AuthorOrCheckerRequiredMixin ): model = Long form_class = LongForm @@ -510,13 +515,9 @@ class LongUpdate( # #initial = {'date_of_death': '05/01/2018'} # exclude = [ 'created_date', 'published_date' ] - def get_form_kwargs(self): - kwargs = super(LongUpdate, self).get_form_kwargs() - kwargs.update({"user": self.request.user}) - return kwargs def get_context_data(self, **kwargs): - context = super(LongUpdate, self).get_context_data(**kwargs) + context = super().get_context_data(**kwargs) if self.request.POST: context["series_formset"] = SeriesFormSet( self.request.POST, self.request.FILES, instance=self.object @@ -563,6 +564,7 @@ class LongUpdate( return super().form_invalid(form) + class LongClone(LongCreateBase): """Clones a existing long""" @@ -643,12 +645,12 @@ class LongSeriesView(LoginRequiredMixin, SingleTableMixin, FilterView): filterset_class = LongSeriesFilter -#@user_is_long_marker +# @user_is_long_marker def mark_answer_override(request, exam_id, question_number, cid): return mark_answer(request, exam_id, question_number, cid, override=True) -#@user_is_long_marker +# @user_is_long_marker @reversion.create_revision() def mark_answer(request, exam_id, question_number, answer_id, override=False): exam = get_object_or_404(Exam, pk=exam_id) @@ -847,7 +849,7 @@ def mark_answer(request, exam_id, question_number, answer_id, override=False): # @user_passes_test(user_is_admin, login_url="/accounts/login") @login_required -#@user_is_long_marker +# @user_is_long_marker def mark(request, exam_id, sk): exam = get_object_or_404(Exam, pk=exam_id) @@ -902,8 +904,6 @@ def mark(request, exam_id, sk): ) - - @login_required @user_is_author_or_long_series_checker def long_series_order_dicom(request, pk): @@ -985,14 +985,20 @@ class ExamAuthorUpdate( form_class = ExamAuthorForm template_name = "author_form.html" + class ExamMarkersUpdate( - RevisionMixin, CheckCanEditMixin, LoginRequiredMixin, AuthorRequiredMixin, UpdateView + RevisionMixin, + CheckCanEditMixin, + LoginRequiredMixin, + AuthorRequiredMixin, + UpdateView, ): model = Exam form_class = ExamMarkerForm template_name = "markers_form.html" + class ExamGroupsUpdate(ExamGroupsUpdateBase): model = Exam form_class = ExamGroupsForm diff --git a/rapids/views.py b/rapids/views.py index b8a5b8d3..086cd0eb 100755 --- a/rapids/views.py +++ b/rapids/views.py @@ -54,6 +54,7 @@ from generic.views import ( ExamUpdateBase, ExamViews, GenericViewBase, + UpdateQuestionMixin, ) from reversion.views import RevisionMixin @@ -374,7 +375,9 @@ class RapidAnswerUpdate(RevisionMixin, AuthorOrCheckerRequiredMixin, UpdateView) return super().form_invalid(form) -class RapidUpdate(RevisionMixin, AuthorOrCheckerRequiredMixin, UpdateView): +class RapidUpdate( + UpdateQuestionMixin,AuthorOrCheckerRequiredMixin +): model = Rapid form_class = RapidForm @@ -382,10 +385,6 @@ class RapidUpdate(RevisionMixin, AuthorOrCheckerRequiredMixin, UpdateView): # #fields = [ 'condition' ] # #initial = {'date_of_death': '05/01/2018'} # exclude = [ 'created_date', 'published_date' ] - def get_form_kwargs(self): - kwargs = super(RapidUpdate, self).get_form_kwargs() - kwargs.update({"user": self.request.user}) - return kwargs def get_context_data(self, **kwargs): context = super(RapidUpdate, self).get_context_data(**kwargs) diff --git a/sbas/views.py b/sbas/views.py index 5c72cd99..4a5b95c8 100644 --- a/sbas/views.py +++ b/sbas/views.py @@ -50,6 +50,7 @@ from generic.views import ( ExamUpdateBase, ExamViews, GenericViewBase, + UpdateQuestionMixin, exam_inactive, ) @@ -317,19 +318,10 @@ class QuestionCreate(QuestionCreateBase): return initial -class QuestionUpdate(RevisionMixin, AuthorOrCheckerRequiredMixin, UpdateView): +class QuestionUpdate(AuthorOrCheckerRequiredMixin, UpdateQuestionMixin): model = Question form_class = QuestionForm - def get_form_kwargs(self): - kwargs = super(QuestionUpdate, self).get_form_kwargs() - kwargs.update({"user": self.request.user}) - return kwargs - - def get_context_data(self, **kwargs): - context = super(QuestionUpdate, self).get_context_data(**kwargs) - return context - def form_valid(self, form): self.object = form.save(commit=False) self.object.save()