Skip to content

Commit 0985636

Browse files
committed
fix: refactor cause visibility and NGO validation in redirections
- abstract cause visibility check into `_check_cause_visibility` method - abstract NGO validation into `_get_ngo_or_404` method - simplify query logic with prefetching adjustments
1 parent 5e3e1a5 commit 0985636

File tree

1 file changed

+34
-24
lines changed

1 file changed

+34
-24
lines changed

backend/donations/views/redirections.py

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from django.conf import settings
77
from django.contrib import messages
88
from django.core.files import File
9-
from django.db.models import Prefetch
9+
from django.db.models import Prefetch, QuerySet
1010
from django.http import Http404, JsonResponse
1111
from django.shortcuts import get_object_or_404, redirect, render
1212
from django.urls import reverse
@@ -80,36 +80,25 @@ def get_context_data(self, cause_slug, **kwargs):
8080

8181
request = self.request
8282

83-
main_cause_qs = Cause.objects.filter(is_main=True).only("id", "slug", "name", "description")
83+
main_cause_qs: QuerySet[Cause] = Cause.objects.filter(is_main=True).only("id", "slug", "name", "description")
84+
85+
prefetch_qs = Cause.active.select_related("ngo").prefetch_related(
86+
Prefetch(
87+
lookup="ngo__causes",
88+
queryset=main_cause_qs,
89+
to_attr="main_cause_list",
90+
)
91+
)
8492

8593
cause: Cause = get_object_or_404(
86-
Cause.active.select_related("ngo").prefetch_related(
87-
Prefetch(
88-
lookup="ngo__causes",
89-
queryset=main_cause_qs,
90-
to_attr="main_cause_list",
91-
)
92-
),
94+
prefetch_qs,
9395
slug=cause_slug,
9496
)
9597

9698
user: User = request.user
97-
if cause.visibility == CauseVisibilityChoices.PRIVATE:
98-
# if the cause is private, we need to check if the user is logged in
99-
# and if the user is allowed to see the cause
100-
if not user.is_authenticated:
101-
raise Http404("Cause not found")
99+
self._check_cause_visibility(cause, user)
102100

103-
if not user.is_staff and cause.ngo != user.ngo:
104-
raise Http404("Cause not found")
105-
106-
# if we didn't find it or the ngo doesn't have an active page
107-
if (ngo := cause.ngo) is None:
108-
logger.exception(f"NGO not found for cause {cause.pk}")
109-
raise Http404
110-
111-
if not ngo.can_create_causes:
112-
raise Http404
101+
ngo = self._get_ngo_or_404(cause)
113102

114103
# noinspection PyUnresolvedReferences
115104
main_cause = cause if cause.is_main else (ngo.main_cause_list[0] if ngo.main_cause_list else None)
@@ -157,6 +146,27 @@ def get_context_data(self, cause_slug, **kwargs):
157146

158147
return context
159148

149+
def _get_ngo_or_404(self, cause: Cause) -> Ngo:
150+
# if we didn't find it or the ngo doesn't have an active page
151+
if (ngo := cause.ngo) is None:
152+
logger.exception(f"NGO not found for cause {cause.pk}")
153+
raise Http404
154+
155+
if not ngo.can_create_causes:
156+
raise Http404
157+
158+
return ngo
159+
160+
def _check_cause_visibility(self, cause: Cause, user: User):
161+
if cause.visibility == CauseVisibilityChoices.PRIVATE:
162+
# if the cause is private, we need to check if the user is logged in
163+
# and if the user is allowed to see the cause
164+
if not user.is_authenticated:
165+
raise Http404("Cause not found")
166+
167+
if not user.is_staff and cause.ngo != user.ngo:
168+
raise Http404("Cause not found")
169+
160170
def _get_cause_website(self, cause: Cause) -> tuple[str, str]:
161171
"""
162172
Extracts the NGO website from the cause and returns a tuple with the full URL and a description.

0 commit comments

Comments
 (0)