diff --git a/generic/forms.py b/generic/forms.py
index 3804798d..81056838 100755
--- a/generic/forms.py
+++ b/generic/forms.py
@@ -11,6 +11,7 @@ from django.forms import (
DateField,
SplitDateTimeField,
SplitDateTimeWidget,
+ Select,
)
from django.forms import inlineformset_factory
from atlas.models import CaseCollection
@@ -26,6 +27,7 @@ from generic.models import (
UserGrades,
UserProfile,
UserUserGroup,
+ QuestionReview
)
from django.contrib.admin.widgets import FilteredSelectMultiple
@@ -831,4 +833,18 @@ class UsersAutocompleteForm(Form):
))
-autocomplete_register(UserAutocomplete)
\ No newline at end of file
+autocomplete_register(UserAutocomplete)
+
+class QuestionReviewForm(ModelForm):
+ class Meta:
+ model = QuestionReview
+ fields = ["status", "comment"]
+ widgets = {
+ "status": Select(attrs={"class": "form-select form-select-sm"}),
+ "comment": TextInput(attrs={"class": "form-control form-control-sm", "placeholder": "Comment (optional)"}),
+ }
+
+ def __init__(self, *args, **kwargs):
+ # Accept an optional `user` for future validation/use
+ self.user = kwargs.pop("user", None)
+ super().__init__(*args, **kwargs)
\ No newline at end of file
diff --git a/generic/templates/generic/partials/question_review_form.html b/generic/templates/generic/partials/question_review_form.html
index a362f02b..879c95e1 100644
--- a/generic/templates/generic/partials/question_review_form.html
+++ b/generic/templates/generic/partials/question_review_form.html
@@ -4,15 +4,13 @@
hx-swap="innerHTML"
class="d-flex gap-2 align-items-start">
{% csrf_token %}
+
-
+ {{ form.status }}
-
+
+ {{ form.comment }}
+
diff --git a/generic/views.py b/generic/views.py
index 07978ddf..95746ae7 100644
--- a/generic/views.py
+++ b/generic/views.py
@@ -2956,6 +2956,7 @@ class GenericViewBase:
"""
from django.contrib.contenttypes.models import ContentType
from generic.models import QuestionReview
+ from .forms import QuestionReviewForm
logger.debug("question_set_review called")
@@ -2971,23 +2972,31 @@ class GenericViewBase:
# form is blank for creating a fresh review.
if request.method == "GET" and request.GET.get("edit"):
if request.GET.get("new"):
- return render(request, "generic/partials/question_review_form.html", {"question": question, "latest": None, "app_name": self.app_name})
- return render(request, "generic/partials/question_review_form.html", {"question": question, "latest": latest, "app_name": self.app_name})
+ form = QuestionReviewForm()
+ return render(request, "generic/partials/question_review_form.html", {"question": question, "latest": None, "form": form, "app_name": self.app_name})
+ # Prefill the form with the latest review values (but we'll create a new review on POST)
+ if latest:
+ form = QuestionReviewForm(initial={"status": latest.status, "comment": latest.comment})
+ else:
+ form = QuestionReviewForm()
+ return render(request, "generic/partials/question_review_form.html", {"question": question, "latest": latest, "form": form, "app_name": self.app_name})
if request.method == "POST":
# Require login to post a review
if not request.user.is_authenticated:
return HttpResponse(status=403)
- status = request.POST.get("status")
- comment = request.POST.get("comment", "")
+ form = QuestionReviewForm(request.POST, user=request.user)
+ if not form.is_valid():
+ # Render the form back with errors
+ return render(request, "generic/partials/question_review_form.html", {"question": question, "latest": latest, "form": form, "app_name": self.app_name})
review = QuestionReview.objects.create(
content_type=ct,
object_id=question.pk,
author=request.user,
- status=status,
- comment=comment,
+ status=form.cleaned_data["status"],
+ comment=form.cleaned_data.get("comment", ""),
)
return render(request, "generic/partials/question_review_block.html", {"review": review, "question": question, "app_name": self.app_name})
@@ -2996,7 +3005,12 @@ class GenericViewBase:
if latest:
return render(request, "generic/partials/question_review_block.html", {"review": latest, "question": question, "app_name": self.app_name})
else:
- return render(request, "generic/partials/question_review_form.html", {"question": question, "latest": latest, "app_name": self.app_name})
+ # Ensure a form is available for the template
+ if latest:
+ form = QuestionReviewForm(initial={"status": latest.status, "comment": latest.comment})
+ else:
+ form = QuestionReviewForm()
+ return render(request, "generic/partials/question_review_form.html", {"question": question, "latest": latest, "form": form, "app_name": self.app_name})
def question_reviews_list(self, request, pk):
"""Return a partial listing all QuestionReview instances for a question."""