diff --git a/generic/views.py b/generic/views.py index df990823..02300386 100644 --- a/generic/views.py +++ b/generic/views.py @@ -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}}) diff --git a/sbas/templates/sbas/question_review_list.html b/sbas/templates/sbas/question_review_list.html index 2547eb3d..d47dcba6 100644 --- a/sbas/templates/sbas/question_review_list.html +++ b/sbas/templates/sbas/question_review_list.html @@ -5,6 +5,16 @@

Showing questions matching the selected filters.

+
+
+ + {% if filters.category %}{% endif %} + {% if filters.status %}{% endif %} + +
+ Clear filters +
+
Active filters: {% if filters.category %}