Skip to content

Commit af9e357

Browse files
committed
fix: regression for final N+1 manager models solution
1 parent 1d631a8 commit af9e357

File tree

4 files changed

+76
-16
lines changed

4 files changed

+76
-16
lines changed

ee/insiders

modules/core/karrio/server/providers/models/carrier.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,11 @@ class Meta:
187187
on_delete=models.SET_NULL,
188188
)
189189

190+
@classmethod
191+
def resolve_context_data(cls, queryset, context):
192+
"""Apply context-aware carrier config resolution."""
193+
return queryset.resolve_config_for(context)
194+
190195
def __str__(self):
191196
return self.carrier_id
192197

@@ -229,10 +234,16 @@ def carrier_config(self):
229234

230235
@property
231236
def config(self) -> dict:
232-
if hasattr(self, '_computed_config'):
233-
return self._computed_config or {}
234-
235-
return getattr(self.carrier_config, "config", {})
237+
if hasattr(self, "_computed_config"):
238+
annotated_config = self._computed_config
239+
if annotated_config is not None:
240+
return annotated_config
241+
# If the annotation didn't resolve (eg. context missing), fall back to DB lookup.
242+
resolved_config = getattr(self.carrier_config, "config", None)
243+
if resolved_config is not None:
244+
return resolved_config
245+
# Return empty dict if no config is found - do NOT fallback to credentials
246+
return {}
236247

237248
@property
238249
def services(self) -> typing.Optional[typing.List[dict]]:

modules/core/karrio/server/providers/serializers/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ def create(
201201
context: serializers.Context,
202202
**kwargs,
203203
) -> providers.Carrier:
204-
config = validated_data.pop("config")
204+
config = validated_data.pop("config", None)
205205
carrier_name = validated_data.pop("carrier_name")
206206
default_capabilities = references.get_carrier_capabilities(carrier_name)
207207
capabilities = lib.identity(

modules/manager/karrio/server/manager/models.py

Lines changed: 59 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,6 @@ def get_queryset(self):
107107

108108
class TrackingManager(models.Manager):
109109
def get_queryset(self):
110-
from karrio.server.providers.models.carrier import Carrier
111-
112-
# Prefetch carrier with config resolution to avoid N+1 queries
113-
carrier_queryset = Carrier.objects.resolve_config_for(None)
114-
115110
return (
116111
super()
117112
.get_queryset()
@@ -120,13 +115,8 @@ def get_queryset(self):
120115
"shipment",
121116
"shipment__recipient",
122117
"shipment__shipper",
123-
"tracking_carrier",
124-
"tracking_carrier__created_by",
125-
"tracking_carrier__rate_sheet",
126118
)
127119
.prefetch_related(
128-
"tracking_carrier__active_users",
129-
models.Prefetch("tracking_carrier", queryset=carrier_queryset),
130120
*(("org",) if conf.settings.MULTI_ORGANIZATIONS else tuple()),
131121
)
132122
)
@@ -553,6 +543,16 @@ def delete(self, *args, **kwargs):
553543
handle = self.address or super()
554544
return handle.delete(*args, **kwargs)
555545

546+
@classmethod
547+
def resolve_context_data(cls, queryset, context):
548+
"""Apply context-aware carrier config resolution for pickup_carrier."""
549+
from karrio.server.providers.models.carrier import Carrier
550+
551+
carrier_queryset = Carrier.objects.resolve_config_for(context)
552+
return queryset.prefetch_related(
553+
models.Prefetch("pickup_carrier", queryset=carrier_queryset),
554+
)
555+
556556
@property
557557
def object_type(self):
558558
return "pickup"
@@ -649,6 +649,16 @@ class Meta:
649649
"Shipment", on_delete=models.CASCADE, related_name="shipment_tracker", null=True
650650
)
651651

652+
@classmethod
653+
def resolve_context_data(cls, queryset, context):
654+
"""Apply context-aware carrier config resolution for tracking_carrier."""
655+
from karrio.server.providers.models.carrier import Carrier
656+
657+
carrier_queryset = Carrier.objects.resolve_config_for(context)
658+
return queryset.prefetch_related(
659+
models.Prefetch("tracking_carrier", queryset=carrier_queryset),
660+
)
661+
652662
@property
653663
def object_type(self):
654664
return "tracker"
@@ -843,6 +853,25 @@ def delete(self, *args, **kwargs):
843853
self.customs and self.customs.delete()
844854
return super().delete(*args, **kwargs)
845855

856+
@classmethod
857+
def resolve_context_data(cls, queryset, context):
858+
"""
859+
Apply context-aware prefetching for carriers with proper config resolution.
860+
This is called by access_by() to ensure carrier configs are resolved for the request context.
861+
"""
862+
from karrio.server.providers.models.carrier import Carrier
863+
864+
# Resolve carrier configs with the request context for user/org-specific config
865+
carrier_queryset = Carrier.objects.resolve_config_for(context)
866+
867+
# Re-apply carrier prefetches with context-aware config resolution
868+
# Note: Manager's get_queryset() already sets up base prefetches with context=None
869+
# This overrides those prefetches with context-aware ones when called via access_by()
870+
return queryset.prefetch_related(
871+
models.Prefetch("carriers", queryset=carrier_queryset),
872+
models.Prefetch("selected_rate_carrier", queryset=carrier_queryset),
873+
)
874+
846875
@property
847876
def object_type(self):
848877
return "shipment"
@@ -962,6 +991,16 @@ class Meta:
962991
related_name="shipment_upload_record",
963992
)
964993

994+
@classmethod
995+
def resolve_context_data(cls, queryset, context):
996+
"""Apply context-aware carrier config resolution for upload_carrier."""
997+
from karrio.server.providers.models.carrier import Carrier
998+
999+
carrier_queryset = Carrier.objects.resolve_config_for(context)
1000+
return queryset.prefetch_related(
1001+
models.Prefetch("upload_carrier", queryset=carrier_queryset),
1002+
)
1003+
9651004
# Computed properties
9661005

9671006
@property
@@ -1029,6 +1068,16 @@ class Meta:
10291068

10301069
manifest_carrier = models.ForeignKey(providers.Carrier, on_delete=models.CASCADE)
10311070

1071+
@classmethod
1072+
def resolve_context_data(cls, queryset, context):
1073+
"""Apply context-aware carrier config resolution for manifest_carrier."""
1074+
from karrio.server.providers.models.carrier import Carrier
1075+
1076+
carrier_queryset = Carrier.objects.resolve_config_for(context)
1077+
return queryset.prefetch_related(
1078+
models.Prefetch("manifest_carrier", queryset=carrier_queryset),
1079+
)
1080+
10321081
# Computed properties
10331082

10341083
@property

0 commit comments

Comments
 (0)