Skip to content

Commit 0547d99

Browse files
committed
chore: update model / admin classes to support suggest_queryset_optimizations, generate get_queryset functions
Refs: LIIK-865
1 parent e6000a8 commit 0547d99

File tree

17 files changed

+313
-57
lines changed

17 files changed

+313
-57
lines changed

city_furniture/admin/furniture_signpost.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,38 @@ class FurnitureSignpostPlanAdmin(
228228
"id",
229229
)
230230

231+
# Generated for FurnitureSignpostPlanAdmin at 2026-02-18 11:40:31+00:00
232+
def get_queryset(self, request):
233+
qs = super().get_queryset(request)
234+
resolver_match = getattr(request, "resolver_match", None)
235+
if not resolver_match or not resolver_match.url_name:
236+
return qs
237+
238+
if resolver_match.url_name.endswith("_changelist"):
239+
return qs.select_related(
240+
"device_type", # n:1 relation in list_display (via device_type_preview -> CityFurnitureDeviceTypeIcon.__str__) # noqa: E501
241+
"device_type__icon_file", # n:1 relation chain in list_display (via device_type_preview -> CityFurnitureDeviceTypeIcon.__str__) # noqa: E501
242+
)
243+
elif resolver_match.url_name.endswith("_change"):
244+
return qs.select_related(
245+
"color", # n:1 relation in fieldsets, fieldsets (via CityFurnitureColor.__str__) # noqa: E501
246+
"created_by", # n:1 relation in fieldsets, readonly_fields, readonly_fields (via User.__str__) # noqa: E501
247+
"device_type", # n:1 relation in fieldsets, readonly_fields (via device_type_preview -> CityFurnitureDeviceTypeIcon.__str__) # noqa: E501
248+
"device_type__icon_file", # n:1 relation chain in readonly_fields (via device_type_preview -> CityFurnitureDeviceTypeIcon.__str__) # noqa: E501
249+
"mount_plan", # n:1 relation in fieldsets, fieldsets (via MountPlan.__str__) # noqa: E501
250+
"mount_plan__mount_type", # n:1 relation chain in fieldsets (via MountPlan.__str__) # noqa: E501
251+
"mount_type", # n:1 relation in fieldsets, fieldsets (via MountType.__str__) # noqa: E501
252+
"owner", # n:1 relation in fieldsets, fieldsets (via Owner.__str__) # noqa: E501
253+
"parent", # n:1 relation in fieldsets, fieldsets (via FurnitureSignpostPlan.__str__) # noqa: E501
254+
"parent__device_type", # n:1 relation chain in fieldsets (via FurnitureSignpostPlan.__str__) # noqa: E501
255+
"plan", # n:1 relation in fieldsets, fieldsets (via Plan.__str__) # noqa: E501
256+
"responsible_entity", # n:1 relation in fieldsets # noqa: E501
257+
"target", # n:1 relation in fieldsets, fieldsets (via CityFurnitureTarget.__str__) # noqa: E501
258+
"updated_by", # n:1 relation in fieldsets, readonly_fields # noqa: E501
259+
)
260+
261+
return qs
262+
231263

232264
@admin.register(FurnitureSignpostReal)
233265
class FurnitureSignpostRealAdmin(
@@ -281,3 +313,35 @@ class FurnitureSignpostRealAdmin(
281313
"installation_status": InstallationStatus.IN_USE,
282314
"condition": Condition.VERY_GOOD,
283315
}
316+
317+
# Generated for FurnitureSignpostRealAdmin at 2026-02-18 11:40:01+00:00
318+
def get_queryset(self, request):
319+
qs = super().get_queryset(request)
320+
resolver_match = getattr(request, "resolver_match", None)
321+
if not resolver_match or not resolver_match.url_name:
322+
return qs
323+
324+
if resolver_match.url_name.endswith("_changelist"):
325+
return qs.select_related(
326+
"device_type", # n:1 relation in list_display (via device_type_preview -> CityFurnitureDeviceTypeIcon.__str__) # noqa: E501
327+
"device_type__icon_file", # n:1 relation chain in list_display (via device_type_preview -> CityFurnitureDeviceTypeIcon.__str__) # noqa: E501
328+
)
329+
elif resolver_match.url_name.endswith("_change"):
330+
return qs.select_related(
331+
"color", # n:1 relation in fieldsets, fieldsets (via CityFurnitureColor.__str__) # noqa: E501
332+
"created_by", # n:1 relation in fieldsets, readonly_fields, readonly_fields (via User.__str__) # noqa: E501
333+
"device_type", # n:1 relation in fieldsets, readonly_fields (via device_type_preview -> CityFurnitureDeviceTypeIcon.__str__) # noqa: E501
334+
"device_type__icon_file", # n:1 relation chain in readonly_fields (via device_type_preview -> CityFurnitureDeviceTypeIcon.__str__) # noqa: E501
335+
"furniture_signpost_plan", # n:1 relation in fieldsets, fieldsets (via FurnitureSignpostPlan.__str__) # noqa: E501
336+
"furniture_signpost_plan__device_type", # n:1 relation chain in fieldsets (via FurnitureSignpostPlan.__str__) # noqa: E501
337+
"mount_real", # n:1 relation in fieldsets, fieldsets (via MountReal.__str__) # noqa: E501
338+
"mount_real__mount_type", # n:1 relation chain in fieldsets (via MountReal.__str__) # noqa: E501
339+
"mount_type", # n:1 relation in fieldsets, fieldsets (via MountType.__str__) # noqa: E501
340+
"owner", # n:1 relation in fieldsets, fieldsets (via Owner.__str__) # noqa: E501
341+
"parent", # n:1 relation in fieldsets # noqa: E501
342+
"responsible_entity", # n:1 relation in fieldsets # noqa: E501
343+
"target", # n:1 relation in fieldsets, fieldsets (via CityFurnitureTarget.__str__) # noqa: E501
344+
"updated_by", # n:1 relation in fieldsets, readonly_fields # noqa: E501
345+
)
346+
347+
return qs

city_furniture/models/common.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from django.utils.translation import gettext_lazy as _
1212
from enumfields import EnumField, EnumIntegerField
1313

14+
from admin_helper.decorators import requires_fields
1415
from city_furniture.enums import CityFurnitureClassType, CityFurnitureDeviceTypeTargetModel, CityFurnitureFunctionType
1516
from cityinfra import settings
1617
from traffic_control.mixins.models import AbstractFileModel, SourceControlModel
@@ -128,6 +129,7 @@ class Meta:
128129
verbose_name = _("City Furniture Device Type")
129130
verbose_name_plural = _("City Furniture Device Types")
130131

132+
@requires_fields("code", "description_fi")
131133
def __str__(self) -> str:
132134
return f"{self.code} - {self.description_fi}"
133135

@@ -219,6 +221,7 @@ class Meta:
219221
verbose_name = _("City Furniture Color")
220222
verbose_name_plural = _("City Furniture Colors")
221223

224+
@requires_fields("name")
222225
def __str__(self):
223226
return self.name
224227

@@ -259,6 +262,7 @@ class Meta:
259262
verbose_name = _("City Furniture Target")
260263
verbose_name_plural = _("City Furniture Targets")
261264

265+
@requires_fields("name_fi")
262266
def __str__(self):
263267
return self.name_fi
264268

city_furniture/models/furniture_signpost.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from django.utils.translation import gettext_lazy as _
66
from enumfields import EnumIntegerField
77

8+
from admin_helper.decorators import requires_fields
89
from city_furniture.enums import CityFurnitureDeviceTypeTargetModel
910
from city_furniture.models.common import CityFurnitureColor, CityFurnitureDeviceType, CityFurnitureTarget
1011
from traffic_control.common_strings import direction_field_verbose_name, direction_help_text
@@ -206,6 +207,7 @@ class FurnitureAbstractSignpost(
206207
class Meta:
207208
abstract = True
208209

210+
@requires_fields("id", "device_type", "text_content_fi")
209211
def __str__(self) -> str:
210212
return f"{self.id} {self.device_type} {self.text_content_fi}"
211213

traffic_control/admin/additional_sign.py

Lines changed: 53 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -261,13 +261,35 @@ class AdditionalSignPlanAdmin(
261261
)
262262
initial_values = shared_initial_values
263263

264+
# Generated for AdditionalSignPlanAdmin at 2026-02-18 13:02:09+00:00
264265
def get_queryset(self, request):
265266
qs = super().get_queryset(request)
266-
return (
267-
qs.prefetch_related("device_type")
268-
.prefetch_related("device_type__icon_file")
269-
.prefetch_related("replacement_to_new")
270-
)
267+
resolver_match = getattr(request, "resolver_match", None)
268+
if not resolver_match or not resolver_match.url_name:
269+
return qs
270+
271+
if resolver_match.url_name.endswith("_changelist"):
272+
return qs.select_related(
273+
"device_type", # n:1 relation in list_display (via content -> get_content_s_rows), list_display (via device_type_preview -> TrafficControlDeviceTypeIcon.__str__) # noqa: E501
274+
"device_type__icon_file", # n:1 relation chain in list_display (via device_type_preview -> TrafficControlDeviceTypeIcon.__str__) # noqa: E501
275+
"replacement_to_new", # 1:1 relation in list_display (via is_replaced_as_str) # noqa: E501
276+
)
277+
elif resolver_match.url_name.endswith("_change"):
278+
return qs.select_related(
279+
"created_by", # n:1 relation in fieldsets, readonly_fields, readonly_fields (via User.__str__) # noqa: E501
280+
"device_type", # n:1 relation in fieldsets, readonly_fields (via device_type_preview -> TrafficControlDeviceTypeIcon.__str__) # noqa: E501
281+
"device_type__icon_file", # n:1 relation chain in readonly_fields (via device_type_preview -> TrafficControlDeviceTypeIcon.__str__) # noqa: E501
282+
"mount_plan", # n:1 relation in fieldsets, fieldsets (via MountPlan.__str__) # noqa: E501
283+
"mount_plan__mount_type", # n:1 relation chain in fieldsets (via MountPlan.__str__) # noqa: E501
284+
"mount_type", # n:1 relation in fieldsets, fieldsets (via MountType.__str__) # noqa: E501
285+
"owner", # n:1 relation in fieldsets, fieldsets (via Owner.__str__) # noqa: E501
286+
"parent", # n:1 relation in fieldsets, fieldsets (via TrafficSignPlan.__str__) # noqa: E501
287+
"parent__device_type", # n:1 relation chain in fieldsets (via TrafficSignPlan.__str__) # noqa: E501
288+
"plan", # n:1 relation in fieldsets, fieldsets (via Plan.__str__) # noqa: E501
289+
"updated_by", # n:1 relation in fieldsets, readonly_fields # noqa: E501
290+
)
291+
292+
return qs
271293

272294

273295
@admin.register(AdditionalSignReal)
@@ -420,23 +442,34 @@ class AdditionalSignRealAdmin(
420442
"installation_status": InstallationStatus.IN_USE,
421443
}
422444

445+
# Generated for AdditionalSignRealAdmin at 2026-02-18 12:01:51+00:00
423446
def get_queryset(self, request):
424447
qs = super().get_queryset(request)
425-
return qs.select_related(
426-
"device_type",
427-
"device_type__icon_file",
428-
"created_by",
429-
"updated_by",
430-
"owner",
431-
"additional_sign_plan",
432-
"mount_real",
433-
# NOTE (2025-12-09 thiago)
434-
# Both mount_real__mount_type and mount_type need to be prefetched independently, since we have visible
435-
# columns that access the "mount_type.__str__" through different routes. Removing either prefetch will
436-
# drastically increase the query count
437-
"mount_real__mount_type",
438-
"mount_type",
439-
)
448+
resolver_match = getattr(request, "resolver_match", None)
449+
if not resolver_match or not resolver_match.url_name:
450+
return qs
451+
452+
if resolver_match.url_name.endswith("_changelist"):
453+
return qs.select_related(
454+
"device_type", # n:1 relation in list_display (via content -> get_content_s_rows), list_display (via device_type_preview -> TrafficControlDeviceTypeIcon.__str__) # noqa: E501
455+
"device_type__icon_file", # n:1 relation chain in list_display (via device_type_preview -> TrafficControlDeviceTypeIcon.__str__) # noqa: E501
456+
)
457+
elif resolver_match.url_name.endswith("_change"):
458+
return qs.select_related(
459+
"additional_sign_plan", # n:1 relation in fieldsets, fieldsets (via AdditionalSignPlan.__str__) # noqa: E501
460+
"created_by", # n:1 relation in fieldsets, readonly_fields, readonly_fields (via User.__str__) # noqa: E501
461+
"device_type", # n:1 relation in fieldsets, readonly_fields (via device_type_preview -> TrafficControlDeviceTypeIcon.__str__) # noqa: E501
462+
"device_type__icon_file", # n:1 relation chain in readonly_fields (via device_type_preview -> TrafficControlDeviceTypeIcon.__str__) # noqa: E501
463+
"mount_real", # n:1 relation in fieldsets, fieldsets (via MountReal.__str__) # noqa: E501
464+
"mount_real__mount_type", # n:1 relation chain in fieldsets (via MountReal.__str__) # noqa: E501
465+
"mount_type", # n:1 relation in fieldsets, fieldsets (via MountType.__str__) # noqa: E501
466+
"owner", # n:1 relation in fieldsets, fieldsets (via Owner.__str__) # noqa: E501
467+
"parent", # n:1 relation in fieldsets, fieldsets (via TrafficSignReal.__str__) # noqa: E501
468+
"parent__device_type", # n:1 relation chain in fieldsets (via TrafficSignReal.__str__) # noqa: E501
469+
"updated_by", # n:1 relation in fieldsets, readonly_fields # noqa: E501
470+
)
471+
472+
return qs
440473

441474

442475
class AdditionalSignPlanInline(BaseAdditionalSignInline):

traffic_control/admin/barrier.py

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -206,13 +206,30 @@ class BarrierPlanAdmin(
206206
)
207207
initial_values = shared_initial_values
208208

209+
# Generated for BarrierPlanAdmin at 2026-02-18 13:03:52+00:00
209210
def get_queryset(self, request):
210211
qs = super().get_queryset(request)
211-
return (
212-
qs.prefetch_related("device_type")
213-
.prefetch_related("device_type__icon_file")
214-
.prefetch_related("replacement_to_new")
215-
)
212+
resolver_match = getattr(request, "resolver_match", None)
213+
if not resolver_match or not resolver_match.url_name:
214+
return qs
215+
216+
if resolver_match.url_name.endswith("_changelist"):
217+
return qs.select_related(
218+
"device_type", # n:1 relation in list_display (via device_type_preview -> TrafficControlDeviceTypeIcon.__str__) # noqa: E501
219+
"device_type__icon_file", # n:1 relation chain in list_display (via device_type_preview -> TrafficControlDeviceTypeIcon.__str__) # noqa: E501
220+
"replacement_to_new", # 1:1 relation in list_display (via is_replaced_as_str) # noqa: E501
221+
)
222+
elif resolver_match.url_name.endswith("_change"):
223+
return qs.select_related(
224+
"created_by", # n:1 relation in fieldsets, readonly_fields, readonly_fields (via User.__str__) # noqa: E501
225+
"device_type", # n:1 relation in fieldsets, readonly_fields (via device_type_preview -> TrafficControlDeviceTypeIcon.__str__) # noqa: E501
226+
"device_type__icon_file", # n:1 relation chain in readonly_fields (via device_type_preview -> TrafficControlDeviceTypeIcon.__str__) # noqa: E501
227+
"owner", # n:1 relation in fieldsets, fieldsets (via Owner.__str__) # noqa: E501
228+
"plan", # n:1 relation in fieldsets, fieldsets (via Plan.__str__) # noqa: E501
229+
"updated_by", # n:1 relation in fieldsets, readonly_fields # noqa: E501
230+
)
231+
232+
return qs
216233

217234

218235
class BarrierRealFileInline(admin.TabularInline):
@@ -327,6 +344,27 @@ class BarrierRealAdmin(
327344
"condition": Condition.VERY_GOOD,
328345
}
329346

347+
# Generated for BarrierRealAdmin at 2026-02-18 11:49:17+00:00
330348
def get_queryset(self, request):
331349
qs = super().get_queryset(request)
332-
return qs.prefetch_related("device_type").prefetch_related("device_type__icon_file")
350+
resolver_match = getattr(request, "resolver_match", None)
351+
if not resolver_match or not resolver_match.url_name:
352+
return qs
353+
354+
if resolver_match.url_name.endswith("_changelist"):
355+
return qs.select_related(
356+
"device_type", # n:1 relation in list_display (via device_type_preview -> TrafficControlDeviceTypeIcon.__str__) # noqa: E501
357+
"device_type__icon_file", # n:1 relation chain in list_display (via device_type_preview -> TrafficControlDeviceTypeIcon.__str__) # noqa: E501
358+
)
359+
elif resolver_match.url_name.endswith("_change"):
360+
return qs.select_related(
361+
"barrier_plan", # n:1 relation in fieldsets, fieldsets (via BarrierPlan.__str__) # noqa: E501
362+
"barrier_plan__device_type", # n:1 relation chain in fieldsets (via BarrierPlan.__str__) # noqa: E501
363+
"created_by", # n:1 relation in fieldsets, readonly_fields, readonly_fields (via User.__str__) # noqa: E501
364+
"device_type", # n:1 relation in fieldsets, readonly_fields (via device_type_preview -> TrafficControlDeviceTypeIcon.__str__) # noqa: E501
365+
"device_type__icon_file", # n:1 relation chain in readonly_fields (via device_type_preview -> TrafficControlDeviceTypeIcon.__str__) # noqa: E501
366+
"owner", # n:1 relation in fieldsets, fieldsets (via Owner.__str__) # noqa: E501
367+
"updated_by", # n:1 relation in fieldsets, readonly_fields # noqa: E501
368+
)
369+
370+
return qs

traffic_control/admin/mount.py

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,9 +196,29 @@ class MountPlanAdmin(
196196
)
197197
initial_values = {}
198198

199+
# Generated for MountPlanAdmin at 2026-02-18 13:04:24+00:00
199200
def get_queryset(self, request):
200201
qs = super().get_queryset(request)
201-
return qs.prefetch_related("mount_type").prefetch_related("replacement_to_new")
202+
resolver_match = getattr(request, "resolver_match", None)
203+
if not resolver_match or not resolver_match.url_name:
204+
return qs
205+
206+
if resolver_match.url_name.endswith("_changelist"):
207+
return qs.select_related(
208+
"mount_type", # n:1 relation in list_display, list_display (via MountType.__str__) # noqa: E501
209+
"replacement_to_new", # 1:1 relation in list_display (via is_replaced_as_str) # noqa: E501
210+
)
211+
elif resolver_match.url_name.endswith("_change"):
212+
return qs.select_related(
213+
"created_by", # n:1 relation in fieldsets, readonly_fields, readonly_fields (via User.__str__) # noqa: E501
214+
"mount_type", # n:1 relation in fieldsets, fieldsets (via MountType.__str__) # noqa: E501
215+
"owner", # n:1 relation in fieldsets, fieldsets (via Owner.__str__) # noqa: E501
216+
"plan", # n:1 relation in fieldsets, fieldsets (via Plan.__str__) # noqa: E501
217+
"portal_type", # n:1 relation in fieldsets, fieldsets (via PortalType.__str__) # noqa: E501
218+
"updated_by", # n:1 relation in fieldsets, readonly_fields # noqa: E501
219+
)
220+
221+
return qs
202222

203223

204224
class MountRealFileInline(admin.TabularInline):
@@ -306,9 +326,29 @@ class MountRealAdmin(
306326
"condition": Condition.VERY_GOOD,
307327
}
308328

329+
# Generated for MountRealAdmin at 2026-02-18 11:57:40+00:00
309330
def get_queryset(self, request):
310331
qs = super().get_queryset(request)
311-
return qs.prefetch_related("mount_type")
332+
resolver_match = getattr(request, "resolver_match", None)
333+
if not resolver_match or not resolver_match.url_name:
334+
return qs
335+
336+
if resolver_match.url_name.endswith("_changelist"):
337+
return qs.select_related(
338+
"mount_type", # n:1 relation in list_display, list_display (via MountType.__str__) # noqa: E501
339+
)
340+
elif resolver_match.url_name.endswith("_change"):
341+
return qs.select_related(
342+
"created_by", # n:1 relation in fieldsets, readonly_fields, readonly_fields (via User.__str__) # noqa: E501
343+
"mount_plan", # n:1 relation in fieldsets, fieldsets (via MountPlan.__str__) # noqa: E501
344+
"mount_plan__mount_type", # n:1 relation chain in fieldsets (via MountPlan.__str__) # noqa: E501
345+
"mount_type", # n:1 relation in fieldsets, fieldsets (via MountType.__str__) # noqa: E501
346+
"owner", # n:1 relation in fieldsets, fieldsets (via Owner.__str__) # noqa: E501
347+
"portal_type", # n:1 relation in fieldsets, fieldsets (via PortalType.__str__) # noqa: E501
348+
"updated_by", # n:1 relation in fieldsets, readonly_fields # noqa: E501
349+
)
350+
351+
return qs
312352

313353

314354
@admin.register(MountType)

0 commit comments

Comments
 (0)