Skip to content

Commit e8bec0f

Browse files
Merge pull request #1207 from syucream/fix/some-nplusone
Mitigate some N+1
2 parents 1d9e07e + f3f71a1 commit e8bec0f

File tree

5 files changed

+16
-12
lines changed

5 files changed

+16
-12
lines changed

acl/api_v2/views.py

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import itertools
2-
31
from django.db.models import Q
42
from django.http import Http404
53
from drf_spectacular.types import OpenApiTypes
@@ -67,7 +65,9 @@ def get(self, request: Request, pk: int) -> Response:
6765
if instance.objtype == ACLObjType.Entity:
6866
attrs = instance.attrs.filter(is_active=True)
6967
acl_history = acl_history + list(
70-
itertools.chain.from_iterable([attr.history.all() for attr in attrs])
68+
EntityAttr.history.filter(aclbase_ptr_id__in=[a.id for a in attrs]).order_by(
69+
"-history_date", "-history_id"
70+
)
7171
)
7272
for attr in attrs:
7373
codename_query |= (
@@ -78,7 +78,9 @@ def get(self, request: Request, pk: int) -> Response:
7878

7979
permissions = HistoricalPermission.objects.filter(codename_query)
8080
permission_history = list(
81-
itertools.chain.from_iterable([p.history.all() for p in permissions])
81+
HistoricalPermission.history.filter(
82+
permission_ptr_id__in=[p.id for p in permissions]
83+
).order_by("-history_date", "-history_id")
8284
)
8385

8486
serializer = ACLHistorySerializer(data=acl_history + permission_history, many=True)

entity/api_v2/views.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ def get_queryset(self):
195195
entity = Entity.objects.filter(id=self.kwargs.get("entity_id"), is_active=True).first()
196196
if not entity:
197197
raise Http404
198-
return self.queryset.filter(schema=entity)
198+
return self.queryset.filter(schema=entity).select_related("schema")
199199

200200
@extend_schema(request=EntryCreateSerializer)
201201
def create(self, request: Request, entity_id: int) -> Response:

job/api_v2/serializers.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from drf_spectacular.utils import extend_schema_field
66
from rest_framework import serializers
77

8+
from airone.lib.acl import ACLObjType
89
from entry.models import Entry
910
from job.models import Job
1011

@@ -34,8 +35,8 @@ class Meta:
3435
@extend_schema_field(JobTargetSerializer())
3536
def get_target(self, obj: Job) -> JobTarget | None:
3637
if obj.target is not None:
37-
sub = obj.target.get_subclass_object()
38-
if isinstance(sub, Entry):
38+
if obj.target.objtype == ACLObjType.Entry:
39+
sub = Entry.objects.filter(id=obj.target.id).select_related("schema").first()
3940
return {
4041
"id": sub.id,
4142
"name": sub.name,
@@ -53,7 +54,7 @@ def get_target(self, obj: Job) -> JobTarget | None:
5354
return None
5455

5556
def get_passed_time(self, obj: Job) -> int:
56-
if obj.is_finished():
57+
if obj.is_finished(with_refresh=False):
5758
return math.floor((obj.updated_at - obj.created_at).total_seconds())
5859
else:
5960
return math.floor((datetime.now(timezone.utc) - obj.created_at).total_seconds())

job/api_v2/views.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ def get_queryset(self) -> QuerySet:
108108
if created_after:
109109
query &= Q(created_at__gte=created_after)
110110

111-
return Job.objects.filter(query).order_by("-created_at")
111+
return Job.objects.filter(query).select_related("target").order_by("-created_at")
112112

113113

114114
class JobRerunAPI(generics.UpdateAPIView):

job/models.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -206,9 +206,10 @@ def is_timeout(self) -> bool:
206206

207207
return datetime.now(pytz.timezone(settings.TIME_ZONE)) > task_expiry
208208

209-
def is_finished(self) -> bool:
210-
# Sync status flag information with the data which is stored in database
211-
self.refresh_from_db(fields=["status"])
209+
def is_finished(self, with_refresh: bool = True) -> bool:
210+
if with_refresh:
211+
# Sync status flag information with the data which is stored in database
212+
self.refresh_from_db(fields=["status"])
212213

213214
# This value indicates that there is no more processing for a job
214215
finished_status: list[JobStatus] = [

0 commit comments

Comments
 (0)