Skip to content

Commit 36e8464

Browse files
committed
fix: prefetch right geo custom zones - permissions added and fix applied to detection_object views
1 parent 8b943e1 commit 36e8464

File tree

4 files changed

+119
-25
lines changed

4 files changed

+119
-25
lines changed
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
from typing import Optional
2+
from core.models.geo_custom_zone import GeoCustomZone, GeoCustomZoneStatus
3+
from core.models.geo_custom_zone_category import GeoCustomZoneCategory
4+
from core.models.user import User, UserRole
5+
from core.permissions.base import BasePermission
6+
from core.repository.geo_custom_zone import GeoCustomZoneRepository
7+
8+
from django.db.models import QuerySet
9+
from django.db.models import Prefetch
10+
11+
12+
class GeoCustomZonePermission(
13+
BasePermission[GeoCustomZone],
14+
):
15+
def __init__(
16+
self, user: User, initial_queryset: Optional[QuerySet[GeoCustomZone]] = None
17+
):
18+
self.repository = GeoCustomZoneRepository(initial_queryset=initial_queryset)
19+
self.user = user
20+
21+
def _get_prefetch(self, lookup_root: str = ""):
22+
if self.user.user_role == UserRole.SUPER_ADMIN:
23+
geo_custom_zones_prefetch = Prefetch(
24+
f"{lookup_root}geo_custom_zones",
25+
queryset=GeoCustomZone.objects.filter(
26+
geo_custom_zone_status=GeoCustomZoneStatus.ACTIVE,
27+
),
28+
)
29+
geo_custom_zones_category_prefetch = Prefetch(
30+
f"{lookup_root}geo_custom_zones__geo_custom_zone_category",
31+
queryset=GeoCustomZoneCategory.objects.filter(
32+
geo_custom_zones__geo_custom_zone_status=GeoCustomZoneStatus.ACTIVE,
33+
),
34+
)
35+
else:
36+
geo_custom_zones_prefetch = Prefetch(
37+
f"{lookup_root}geo_custom_zones",
38+
queryset=GeoCustomZone.objects.filter(
39+
geo_custom_zone_status=GeoCustomZoneStatus.ACTIVE,
40+
user_groups_custom_geo_zones__user_user_groups__user=self.user.id,
41+
),
42+
)
43+
geo_custom_zones_category_prefetch = Prefetch(
44+
f"{lookup_root}geo_custom_zones__geo_custom_zone_category",
45+
queryset=GeoCustomZoneCategory.objects.filter(
46+
geo_custom_zones__geo_custom_zone_status=GeoCustomZoneStatus.ACTIVE,
47+
geo_custom_zones__user_groups_custom_geo_zones__user_user_groups__user=self.user.id,
48+
),
49+
)
50+
51+
return geo_custom_zones_prefetch, geo_custom_zones_category_prefetch
52+
53+
def get_detection_object_prefetch(self):
54+
return self._get_prefetch()
55+
56+
def get_detection_prefetch(self):
57+
return self._get_prefetch("detection_object__")

core/repository/geo_custom_zone.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
from typing import List, Optional
2+
from core.models.geo_custom_zone import GeoCustomZone
3+
from core.repository.base import (
4+
BaseRepository,
5+
DateRepoFilter,
6+
TimestampedBaseRepositoryMixin,
7+
UuidBaseRepositoryMixin,
8+
)
9+
from django.db.models import QuerySet
10+
11+
12+
class GeoCustomZoneRepository(
13+
BaseRepository[GeoCustomZone],
14+
TimestampedBaseRepositoryMixin[GeoCustomZone],
15+
UuidBaseRepositoryMixin[GeoCustomZone],
16+
):
17+
def __init__(self, initial_queryset: Optional[QuerySet[GeoCustomZone]] = None):
18+
self.model = GeoCustomZone
19+
self.initial_queryset = (
20+
initial_queryset if initial_queryset is not None else self.model.objects
21+
)
22+
23+
def filter_(
24+
self,
25+
queryset: QuerySet[GeoCustomZone],
26+
filter_created_at: Optional[DateRepoFilter] = None,
27+
filter_updated_at: Optional[DateRepoFilter] = None,
28+
filter_uuid_in: Optional[List[str]] = None,
29+
filter_uuid_notin: Optional[List[str]] = None,
30+
order_bys: Optional[List[str]] = None,
31+
*args,
32+
**kwargs,
33+
) -> QuerySet[GeoCustomZone]:
34+
# mixin filters
35+
36+
queryset = self._filter_timestamped(
37+
queryset=queryset,
38+
filter_created_at=filter_created_at,
39+
filter_updated_at=filter_updated_at,
40+
)
41+
queryset = self._filter_uuid(
42+
queryset=queryset,
43+
filter_uuid_in=filter_uuid_in,
44+
filter_uuid_notin=filter_uuid_notin,
45+
)
46+
47+
queryset = self.order_by(queryset=queryset, order_bys=order_bys)
48+
49+
return queryset

core/views/detection/detection_list.py

Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,8 @@
2222
DetectionPrescriptionStatus,
2323
DetectionValidationStatus,
2424
)
25-
from core.models.geo_custom_zone import GeoCustomZone, GeoCustomZoneStatus
26-
from core.models.geo_custom_zone_category import GeoCustomZoneCategory
2725
from core.models.tile_set import TileSet, TileSetStatus, TileSetType
28-
from core.models.user import UserRole
26+
from core.permissions.geo_custom_zone import GeoCustomZonePermission
2927
from core.permissions.tile_set import TileSetPermission
3028
from core.permissions.user import UserPermission
3129
from core.repository.base import NumberRepoFilter, RepoFilterLookup
@@ -279,27 +277,9 @@ def filter_queryset(self, queryset):
279277
"detection_object__commune__geometry",
280278
)
281279

282-
# TODO: move this in permission file and apply this to geo
283-
if self.request.user.user_role == UserRole.SUPER_ADMIN:
284-
geo_custom_zones_prefetch = Prefetch("detection_object__geo_custom_zones")
285-
geo_custom_zones_category_prefetch = Prefetch(
286-
"detection_object__geo_custom_zones__geo_custom_zone_category"
287-
)
288-
else:
289-
geo_custom_zones_prefetch = Prefetch(
290-
"detection_object__geo_custom_zones",
291-
queryset=GeoCustomZone.objects.filter(
292-
geo_custom_zone_status=GeoCustomZoneStatus.ACTIVE,
293-
user_groups_custom_geo_zones__user_user_groups__user=self.request.user.id,
294-
),
295-
)
296-
geo_custom_zones_category_prefetch = Prefetch(
297-
"detection_object__geo_custom_zones__geo_custom_zone_category",
298-
queryset=GeoCustomZoneCategory.objects.filter(
299-
geo_custom_zones__geo_custom_zone_status=GeoCustomZoneStatus.ACTIVE,
300-
geo_custom_zones__user_groups_custom_geo_zones__user_user_groups__user=self.request.user.id,
301-
),
302-
)
280+
geo_custom_zones_prefetch, geo_custom_zones_category_prefetch = (
281+
GeoCustomZonePermission(user=self.request.user).get_detection_prefetch()
282+
)
303283

304284
queryset = queryset.prefetch_related(
305285
"detection_object",

core/views/detection_object.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from core.contants.geo import SRID
77
from core.models.detection_object import DetectionObject
88
from core.models.tile_set import TileSetType
9+
from core.permissions.geo_custom_zone import GeoCustomZonePermission
910
from core.permissions.tile_set import TileSetPermission
1011
from core.serializers.detection_object import (
1112
DetectionObjectDetailSerializer,
@@ -91,8 +92,15 @@ def get_queryset(self):
9192
queryset = queryset.defer("parcel__geometry")
9293

9394
if self.action == "retrieve":
95+
geo_custom_zones_prefetch, geo_custom_zones_category_prefetch = (
96+
GeoCustomZonePermission(
97+
user=self.request.user
98+
).get_detection_object_prefetch()
99+
)
100+
94101
queryset = queryset.prefetch_related(
95-
"geo_custom_zones", "geo_sub_custom_zones"
102+
geo_custom_zones_prefetch,
103+
geo_custom_zones_category_prefetch,
96104
)
97105
queryset = queryset.defer(
98106
"geo_custom_zones__geometry", "geo_sub_custom_zones__geometry"

0 commit comments

Comments
 (0)