Implement query optimization

This commit is contained in:
2026-01-17 22:59:23 +01:00
parent cfc7531b59
commit 792b60cdc6
9 changed files with 568 additions and 34 deletions

View File

@@ -96,6 +96,16 @@ class GetData(View):
def get_data(self, request):
return (
RollingStock.objects.get_published(request.user)
.select_related(
'rolling_class',
'rolling_class__company',
'rolling_class__type',
'manufacturer',
'scale',
'decoder',
'shop',
)
.prefetch_related('tags', 'image')
.order_by(*get_items_ordering())
.filter(self.filter)
)
@@ -132,6 +142,16 @@ class GetHome(GetData):
max_items = min(settings.FEATURED_ITEMS_MAX, get_items_per_page())
return (
RollingStock.objects.get_published(request.user)
.select_related(
'rolling_class',
'rolling_class__company',
'rolling_class__type',
'manufacturer',
'scale',
'decoder',
'shop',
)
.prefetch_related('tags', 'image')
.filter(featured=True)
.order_by(*get_items_ordering(config="featured_items_ordering"))[
:max_items
@@ -200,6 +220,14 @@ class SearchObjects(View):
# and manufacturer as well
roster = (
RollingStock.objects.get_published(request.user)
.select_related(
'rolling_class',
'rolling_class__company',
'rolling_class__type',
'manufacturer',
'scale',
)
.prefetch_related('tags', 'image')
.filter(query)
.distinct()
.order_by(*get_items_ordering())
@@ -209,6 +237,8 @@ class SearchObjects(View):
if _filter is None:
consists = (
Consist.objects.get_published(request.user)
.select_related('company', 'scale')
.prefetch_related('tags', 'consist_item')
.filter(
Q(
Q(identifier__icontains=search)
@@ -220,6 +250,7 @@ class SearchObjects(View):
data = list(chain(data, consists))
books = (
Book.objects.get_published(request.user)
.prefetch_related('toc', 'image')
.filter(
Q(
Q(title__icontains=search)
@@ -231,6 +262,8 @@ class SearchObjects(View):
)
catalogs = (
Catalog.objects.get_published(request.user)
.select_related('manufacturer')
.prefetch_related('scales', 'image')
.filter(
Q(
Q(manufacturer__name__icontains=search)
@@ -242,6 +275,8 @@ class SearchObjects(View):
data = list(chain(data, books, catalogs))
magazine_issues = (
MagazineIssue.objects.get_published(request.user)
.select_related('magazine')
.prefetch_related('toc', 'image')
.filter(
Q(
Q(magazine__name__icontains=search)
@@ -331,9 +366,16 @@ class GetManufacturerItem(View):
)
if search != "all":
roster = get_list_or_404(
RollingStock.objects.get_published(request.user).order_by(
*get_items_ordering()
),
RollingStock.objects.get_published(request.user)
.select_related(
'rolling_class',
'rolling_class__company',
'rolling_class__type',
'manufacturer',
'scale',
)
.prefetch_related('image')
.order_by(*get_items_ordering()),
Q(
Q(manufacturer=manufacturer)
& Q(item_number_slug__exact=search)
@@ -349,6 +391,14 @@ class GetManufacturerItem(View):
else:
roster = (
RollingStock.objects.get_published(request.user)
.select_related(
'rolling_class',
'rolling_class__company',
'rolling_class__type',
'manufacturer',
'scale',
)
.prefetch_related('image')
.filter(
Q(manufacturer=manufacturer)
| Q(rolling_class__manufacturer=manufacturer)
@@ -356,8 +406,11 @@ class GetManufacturerItem(View):
.distinct()
.order_by(*get_items_ordering())
)
catalogs = Catalog.objects.get_published(request.user).filter(
manufacturer=manufacturer
catalogs = (
Catalog.objects.get_published(request.user)
.select_related('manufacturer')
.prefetch_related('scales', 'image')
.filter(manufacturer=manufacturer)
)
title = "Manufacturer: {0}".format(manufacturer)
@@ -405,6 +458,14 @@ class GetObjectsFiltered(View):
roster = (
RollingStock.objects.get_published(request.user)
.select_related(
'rolling_class',
'rolling_class__company',
'rolling_class__type',
'manufacturer',
'scale',
)
.prefetch_related('tags', 'image')
.filter(query)
.distinct()
.order_by(*get_items_ordering())
@@ -415,6 +476,8 @@ class GetObjectsFiltered(View):
if _filter == "scale":
catalogs = (
Catalog.objects.get_published(request.user)
.select_related('manufacturer')
.prefetch_related('scales', 'image')
.filter(scales__slug=search)
.distinct()
)
@@ -423,6 +486,8 @@ class GetObjectsFiltered(View):
try: # Execute only if query_2nd is defined
consists = (
Consist.objects.get_published(request.user)
.select_related('company', 'scale')
.prefetch_related('tags', 'consist_item')
.filter(query_2nd)
.distinct()
)
@@ -430,16 +495,21 @@ class GetObjectsFiltered(View):
if _filter == "tag": # Books can be filtered only by tag
books = (
Book.objects.get_published(request.user)
.prefetch_related('toc', 'tags', 'image')
.filter(query_2nd)
.distinct()
)
catalogs = (
Catalog.objects.get_published(request.user)
.select_related('manufacturer')
.prefetch_related('scales', 'tags', 'image')
.filter(query_2nd)
.distinct()
)
magazine_issues = (
MagazineIssue.objects.get_published(request.user)
.select_related('magazine')
.prefetch_related('toc', 'tags', 'image')
.filter(query_2nd)
.distinct()
)
@@ -477,9 +547,29 @@ class GetObjectsFiltered(View):
class GetRollingStock(View):
def get(self, request, uuid):
try:
rolling_stock = RollingStock.objects.get_published(
request.user
).get(uuid=uuid)
rolling_stock = (
RollingStock.objects.get_published(request.user)
.select_related(
'rolling_class',
'rolling_class__company',
'rolling_class__type',
'manufacturer',
'scale',
'decoder',
'shop',
)
.prefetch_related(
'tags',
'image',
'property',
'document',
'journal',
'rolling_class__property',
'rolling_class__manufacturer',
'decoder__document',
)
.get(uuid=uuid)
)
except ObjectDoesNotExist:
raise Http404
@@ -498,13 +588,22 @@ class GetRollingStock(View):
)
consists = list(
Consist.objects.get_published(request.user).filter(
consist_item__rolling_stock=rolling_stock
)
Consist.objects.get_published(request.user)
.select_related('company', 'scale')
.prefetch_related('tags', 'consist_item')
.filter(consist_item__rolling_stock=rolling_stock)
)
trainset = list(
RollingStock.objects.get_published(request.user)
.select_related(
'rolling_class',
'rolling_class__company',
'rolling_class__type',
'manufacturer',
'scale',
)
.prefetch_related('image')
.filter(
Q(
Q(item_number__exact=rolling_stock.item_number)
@@ -535,30 +634,62 @@ class Consists(GetData):
title = "Consists"
def get_data(self, request):
return Consist.objects.get_published(request.user).all()
return (
Consist.objects.get_published(request.user)
.select_related('company', 'scale')
.prefetch_related('tags', 'consist_item')
.all()
)
class GetConsist(View):
def get(self, request, uuid, page=1):
try:
consist = Consist.objects.get_published(request.user).get(
uuid=uuid
consist = (
Consist.objects.get_published(request.user)
.select_related('company', 'scale')
.prefetch_related(
'tags',
'consist_item',
'consist_item__rolling_stock',
'consist_item__rolling_stock__rolling_class',
'consist_item__rolling_stock__rolling_class__company',
'consist_item__rolling_stock__rolling_class__type',
'consist_item__rolling_stock__manufacturer',
'consist_item__rolling_stock__scale',
'consist_item__rolling_stock__image',
)
.get(uuid=uuid)
)
except ObjectDoesNotExist:
raise Http404
# Fetch consist items with related rolling stock in one query
consist_items = consist.consist_item.select_related(
'rolling_stock',
'rolling_stock__rolling_class',
'rolling_stock__rolling_class__company',
'rolling_stock__rolling_class__type',
'rolling_stock__manufacturer',
'rolling_stock__scale',
).prefetch_related('rolling_stock__image')
# Filter items and loads
data = list(
RollingStock.objects.get_published(request.user).get(
uuid=r.rolling_stock_id
)
for r in consist.consist_item.filter(load=False)
item.rolling_stock
for item in consist_items.filter(load=False)
if RollingStock.objects.get_published(request.user)
.filter(uuid=item.rolling_stock_id)
.exists()
)
loads = list(
RollingStock.objects.get_published(request.user).get(
uuid=r.rolling_stock_id
)
for r in consist.consist_item.filter(load=True)
item.rolling_stock
for item in consist_items.filter(load=True)
if RollingStock.objects.get_published(request.user)
.filter(uuid=item.rolling_stock_id)
.exists()
)
paginator = Paginator(data, get_items_per_page())
data = paginator.get_page(page)
page_range = paginator.get_elided_page_range(
@@ -739,14 +870,23 @@ class Books(GetData):
title = "Books"
def get_data(self, request):
return Book.objects.get_published(request.user).all()
return (
Book.objects.get_published(request.user)
.prefetch_related('tags', 'image', 'toc')
.all()
)
class Catalogs(GetData):
title = "Catalogs"
def get_data(self, request):
return Catalog.objects.get_published(request.user).all()
return (
Catalog.objects.get_published(request.user)
.select_related('manufacturer')
.prefetch_related('scales', 'tags', 'image')
.all()
)
class Magazines(GetData):
@@ -755,6 +895,8 @@ class Magazines(GetData):
def get_data(self, request):
return (
Magazine.objects.get_published(request.user)
.select_related('publisher')
.prefetch_related('tags')
.order_by(Lower("name"))
.annotate(
issues=Count(
@@ -772,12 +914,19 @@ class Magazines(GetData):
class GetMagazine(View):
def get(self, request, uuid, page=1):
try:
magazine = Magazine.objects.get_published(request.user).get(
uuid=uuid
magazine = (
Magazine.objects.get_published(request.user)
.select_related('publisher')
.prefetch_related('tags')
.get(uuid=uuid)
)
except ObjectDoesNotExist:
raise Http404
data = list(magazine.issue.get_published(request.user).all())
data = list(
magazine.issue.get_published(request.user)
.prefetch_related('image', 'toc')
.all()
)
paginator = Paginator(data, get_items_per_page())
data = paginator.get_page(page)
page_range = paginator.get_elided_page_range(
@@ -800,9 +949,11 @@ class GetMagazine(View):
class GetMagazineIssue(View):
def get(self, request, uuid, magazine, page=1):
try:
issue = MagazineIssue.objects.get_published(request.user).get(
uuid=uuid,
magazine__uuid=magazine,
issue = (
MagazineIssue.objects.get_published(request.user)
.select_related('magazine')
.prefetch_related('property', 'document', 'image', 'toc')
.get(uuid=uuid, magazine__uuid=magazine)
)
except ObjectDoesNotExist:
raise Http404
@@ -823,9 +974,18 @@ class GetMagazineIssue(View):
class GetBookCatalog(View):
def get_object(self, request, uuid, selector):
if selector == "book":
return Book.objects.get_published(request.user).get(uuid=uuid)
return (
Book.objects.get_published(request.user)
.prefetch_related('property', 'document', 'image', 'toc', 'tags')
.get(uuid=uuid)
)
elif selector == "catalog":
return Catalog.objects.get_published(request.user).get(uuid=uuid)
return (
Catalog.objects.get_published(request.user)
.select_related('manufacturer')
.prefetch_related('property', 'document', 'image', 'scales', 'tags')
.get(uuid=uuid)
)
else:
raise Http404