Add QuestionReviewForm for handling question review submissions and update views for form integration

This commit is contained in:
Ross
2025-10-22 22:00:05 +01:00
parent e819645278
commit be68fcd0b9
3 changed files with 43 additions and 15 deletions
+17 -1
View File
@@ -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)
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)
@@ -4,15 +4,13 @@
hx-swap="innerHTML"
class="d-flex gap-2 align-items-start">
{% csrf_token %}
<div class="form-select-sm">
<select name="status" class="form-select form-select-sm">
<option value="AC" {% if latest and latest.status == 'AC' %}selected{% endif %}>Accepted</option>
<option value="OD" {% if latest and latest.status == 'OD' %}selected{% endif %}>Outdated</option>
<option value="ER" {% if latest and latest.status == 'ER' %}selected{% endif %}>Error</option>
<option value="RJ" {% if latest and latest.status == 'RJ' %}selected{% endif %}>Rejected</option>
</select>
{{ form.status }}
</div>
<input type="text" name="comment" class="form-control form-control-sm" placeholder="Comment (optional)" value="{% if latest %}{{ latest.comment }}{% endif %}">
{{ form.comment }}
<div>
<button class="btn btn-sm btn-primary" type="submit">Save</button>
</div>
+21 -7
View File
@@ -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."""