mirror of
https://github.com/daniviga/django-ram.git
synced 2026-02-04 01:50:39 +01:00
Improve performance oprimizing queries (#56)
* Extend test coverage * Implement query optimization * More aggressing code reuse * Add more indexes and optimize usage * Fix tests * Further optimizations, improve counting to rely on backend DB * chore: add Makefile for frontend asset minification - Add comprehensive Makefile with targets for JS and CSS minification - Implements instructions from ram/portal/static/js/src/README.md - Provides targets: install, minify, minify-js, minify-css, clean, watch - Fix main.min.js to only include theme_selector.js and tabs_selector.js - Remove validators.js from minified output per README instructions * Add a Makefile to compile JS and CSS * docs: add blank line whitespace rule to AGENTS.md Specify that blank lines must not contain any whitespace (spaces or tabs) to maintain code cleanliness and PEP 8 compliance * Update for 0.20 release with optimizations * Improve Makefile
This commit is contained in:
@@ -158,6 +158,11 @@ class RollingStockAdmin(SortableAdminBase, admin.ModelAdmin):
|
||||
)
|
||||
save_as = True
|
||||
|
||||
def get_queryset(self, request):
|
||||
"""Optimize queryset with select_related and prefetch_related."""
|
||||
qs = super().get_queryset(request)
|
||||
return qs.with_related()
|
||||
|
||||
@admin.display(description="Country")
|
||||
def country_flag(self, obj):
|
||||
return format_html(
|
||||
@@ -268,6 +273,18 @@ class RollingStockAdmin(SortableAdminBase, admin.ModelAdmin):
|
||||
"Properties",
|
||||
]
|
||||
data = []
|
||||
|
||||
# Prefetch related data to avoid N+1 queries
|
||||
queryset = queryset.select_related(
|
||||
'rolling_class',
|
||||
'rolling_class__type',
|
||||
'rolling_class__company',
|
||||
'manufacturer',
|
||||
'scale',
|
||||
'decoder',
|
||||
'shop'
|
||||
).prefetch_related('tags', 'property__property')
|
||||
|
||||
for obj in queryset:
|
||||
properties = settings.CSV_SEPARATOR_ALT.join(
|
||||
"{}:{}".format(property.property.name, property.value)
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
# Generated by Django 6.0.1 on 2026-01-18 13:42
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
(
|
||||
"metadata",
|
||||
"0027_company_company_slug_idx_company_company_country_idx_and_more",
|
||||
),
|
||||
("roster", "0040_alter_rollingstock_decoder_interface_order"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddIndex(
|
||||
model_name="rollingclass",
|
||||
index=models.Index(fields=["company"], name="roster_rc_company_idx"),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name="rollingclass",
|
||||
index=models.Index(fields=["type"], name="roster_rc_type_idx"),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name="rollingclass",
|
||||
index=models.Index(
|
||||
fields=["company", "identifier"], name="roster_rc_co_ident_idx"
|
||||
),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name="rollingstock",
|
||||
index=models.Index(fields=["published"], name="roster_published_idx"),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name="rollingstock",
|
||||
index=models.Index(fields=["featured"], name="roster_featured_idx"),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name="rollingstock",
|
||||
index=models.Index(
|
||||
fields=["item_number_slug"], name="roster_item_slug_idx"
|
||||
),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name="rollingstock",
|
||||
index=models.Index(fields=["road_number_int"], name="roster_road_num_idx"),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name="rollingstock",
|
||||
index=models.Index(
|
||||
fields=["published", "featured"], name="roster_pub_feat_idx"
|
||||
),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name="rollingstock",
|
||||
index=models.Index(
|
||||
fields=["manufacturer", "item_number_slug"], name="roster_mfr_item_idx"
|
||||
),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name="rollingstock",
|
||||
index=models.Index(fields=["scale"], name="roster_scale_idx"),
|
||||
),
|
||||
]
|
||||
@@ -11,7 +11,7 @@ from tinymce import models as tinymce
|
||||
|
||||
from ram.models import BaseModel, Image, PropertyInstance
|
||||
from ram.utils import DeduplicatedStorage, slugify
|
||||
from ram.managers import PublicManager
|
||||
from ram.managers import RollingStockManager
|
||||
from metadata.models import (
|
||||
Scale,
|
||||
Manufacturer,
|
||||
@@ -38,6 +38,14 @@ class RollingClass(models.Model):
|
||||
ordering = ["company", "identifier"]
|
||||
verbose_name = "Class"
|
||||
verbose_name_plural = "Classes"
|
||||
indexes = [
|
||||
models.Index(fields=["company"], name="roster_rc_company_idx"),
|
||||
models.Index(fields=["type"], name="roster_rc_type_idx"),
|
||||
models.Index(
|
||||
fields=["company", "identifier"],
|
||||
name="roster_rc_co_ident_idx", # Shortened to fit 30 char limit
|
||||
),
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
return "{0} {1}".format(self.company, self.identifier)
|
||||
@@ -120,9 +128,35 @@ class RollingStock(BaseModel):
|
||||
Tag, related_name="rolling_stock", blank=True
|
||||
)
|
||||
|
||||
objects = RollingStockManager()
|
||||
|
||||
class Meta:
|
||||
ordering = ["rolling_class", "road_number_int"]
|
||||
verbose_name_plural = "Rolling stock"
|
||||
indexes = [
|
||||
# Index for published/featured filtering
|
||||
models.Index(fields=["published"], name="roster_published_idx"),
|
||||
models.Index(fields=["featured"], name="roster_featured_idx"),
|
||||
# Index for item number searches
|
||||
models.Index(
|
||||
fields=["item_number_slug"], name="roster_item_slug_idx"
|
||||
),
|
||||
# Index for road number searches and ordering
|
||||
models.Index(
|
||||
fields=["road_number_int"], name="roster_road_num_idx"
|
||||
),
|
||||
# Composite index for common filtering patterns
|
||||
models.Index(
|
||||
fields=["published", "featured"], name="roster_pub_feat_idx"
|
||||
),
|
||||
# Composite index for manufacturer+item_number lookups
|
||||
models.Index(
|
||||
fields=["manufacturer", "item_number_slug"],
|
||||
name="roster_mfr_item_idx",
|
||||
),
|
||||
# Index for scale filtering
|
||||
models.Index(fields=["scale"], name="roster_scale_idx"),
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
return "{0} {1}".format(self.rolling_class, self.road_number)
|
||||
@@ -248,7 +282,7 @@ class RollingStockJournal(models.Model):
|
||||
class Meta:
|
||||
ordering = ["date", "rolling_stock"]
|
||||
|
||||
objects = PublicManager()
|
||||
objects = RollingStockManager()
|
||||
|
||||
|
||||
# @receiver(models.signals.post_delete, sender=Cab)
|
||||
|
||||
Reference in New Issue
Block a user