Add filtering option for questions reviewed by the current user in question review list
This commit is contained in:
@@ -3085,6 +3085,21 @@ class GenericViewBase:
|
||||
# Build base queryset of questions for this app
|
||||
qs = self.question_object.objects.all().order_by("pk")
|
||||
|
||||
# Optionally restrict iteration to questions reviewed by the current user
|
||||
reviewed_filter = (request.POST.get("reviewed") or request.GET.get("reviewed")) == "me"
|
||||
if reviewed_filter:
|
||||
try:
|
||||
from django.db.models import Exists, OuterRef
|
||||
|
||||
# use the module-level ContentType (imported near file top)
|
||||
ct = ContentType.objects.get_for_model(self.question_object)
|
||||
reviewed_exists = QuestionReview.objects.filter(
|
||||
content_type=ct, object_id=OuterRef("pk"), author=request.user
|
||||
)
|
||||
qs = qs.annotate(reviewed_by_me=Exists(reviewed_exists))
|
||||
except Exception:
|
||||
reviewed_filter = True
|
||||
|
||||
# Restrict by category if provided and the model has such a relation
|
||||
if category:
|
||||
try:
|
||||
@@ -3153,6 +3168,23 @@ class GenericViewBase:
|
||||
# Build base queryset of questions for this app
|
||||
qs = self.question_object.objects.all().order_by("pk")
|
||||
|
||||
# Optionally filter to questions reviewed by the current user.
|
||||
# Use an Exists subquery to avoid fetching extra rows.
|
||||
reviewed_filter = (request.GET.get("reviewed") or request.POST.get("reviewed")) == "me"
|
||||
if reviewed_filter:
|
||||
try:
|
||||
from django.db.models import Exists, OuterRef
|
||||
|
||||
# use the module-level ContentType (imported near file top)
|
||||
ct = ContentType.objects.get_for_model(self.question_object)
|
||||
reviewed_exists = QuestionReview.objects.filter(
|
||||
content_type=ct, object_id=OuterRef("pk"), author=request.user
|
||||
)
|
||||
qs = qs.annotate(reviewed_by_me=Exists(reviewed_exists))
|
||||
except Exception:
|
||||
# If annotation fails for any reason, fall back to no-op and we'll filter in Python loop
|
||||
reviewed_filter = True
|
||||
|
||||
# Restrict by category if provided
|
||||
if category:
|
||||
try:
|
||||
@@ -3194,6 +3226,19 @@ class GenericViewBase:
|
||||
match = True
|
||||
|
||||
if match:
|
||||
# If the caller requested only questions reviewed by the current user,
|
||||
# skip any question that does not have a matching review.
|
||||
if reviewed_filter:
|
||||
# If annotation was applied this attribute will be present on the instance.
|
||||
if hasattr(question, "reviewed_by_me"):
|
||||
if not question.reviewed_by_me:
|
||||
continue
|
||||
else:
|
||||
# Last-resort check via DB lookup
|
||||
ct = ContentType.objects.get_for_model(question)
|
||||
if not QuestionReview.objects.filter(content_type=ct, object_id=question.pk, author=request.user).exists():
|
||||
continue
|
||||
|
||||
results.append(question)
|
||||
|
||||
return render(request, f"{self.app_name}/question_review_list.html", {"questions": results, "app_name": self.app_name, "filters": {"category": category, "status": status}})
|
||||
|
||||
@@ -5,6 +5,16 @@
|
||||
|
||||
<p>Showing questions matching the selected filters.</p>
|
||||
|
||||
<div class="mb-2">
|
||||
<form method="get" class="d-inline">
|
||||
<input type="hidden" name="reviewed" value="me" />
|
||||
{% if filters.category %}<input type="hidden" name="category" value="{{ filters.category }}" />{% endif %}
|
||||
{% if filters.status %}<input type="hidden" name="status" value="{{ filters.status }}" />{% endif %}
|
||||
<button type="submit" class="btn btn-sm btn-outline-primary">Show only questions I've reviewed</button>
|
||||
</form>
|
||||
<a href="?" class="btn btn-sm btn-outline-secondary ms-2">Clear filters</a>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
Active filters:
|
||||
{% if filters.category %}
|
||||
|
||||
Reference in New Issue
Block a user