From 49c8d804d6c5368bdd1bd27558a1aa6198458f32 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniele=20Vigan=C3=B2?=
Date: Sat, 3 Jan 2026 14:18:46 +0100
Subject: [PATCH] Implement support for rolling stock load in consists
---
.../migrations/0019_consistitem_load.py | 18 +++++++++++
ram/consist/models.py | 12 +++++--
ram/portal/templates/consist.html | 31 +++++++++++++++++--
ram/portal/views.py | 9 +++++-
ram/ram/__init__.py | 2 +-
5 files changed, 65 insertions(+), 7 deletions(-)
create mode 100644 ram/consist/migrations/0019_consistitem_load.py
diff --git a/ram/consist/migrations/0019_consistitem_load.py b/ram/consist/migrations/0019_consistitem_load.py
new file mode 100644
index 0000000..7a789f6
--- /dev/null
+++ b/ram/consist/migrations/0019_consistitem_load.py
@@ -0,0 +1,18 @@
+# Generated by Django 6.0 on 2026-01-03 12:31
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("consist", "0018_alter_consist_scale"),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name="consistitem",
+ name="load",
+ field=models.BooleanField(default=False),
+ ),
+ ]
diff --git a/ram/consist/models.py b/ram/consist/models.py
index 8077c3d..157bb5d 100644
--- a/ram/consist/models.py
+++ b/ram/consist/models.py
@@ -43,10 +43,10 @@ class Consist(BaseModel):
@property
def length(self):
- return self.consist_item.count()
+ return self.consist_item.filter(load=False).count()
def get_type_count(self):
- return self.consist_item.annotate(
+ return self.consist_item.filter(load=False).annotate(
type=models.F("rolling_stock__rolling_class__type__type")
).values(
"type"
@@ -69,6 +69,7 @@ class ConsistItem(models.Model):
Consist, on_delete=models.CASCADE, related_name="consist_item"
)
rolling_stock = models.ForeignKey(RollingStock, on_delete=models.CASCADE)
+ load = models.BooleanField(default=False)
order = models.PositiveIntegerField(blank=False, null=False)
class Meta:
@@ -92,10 +93,15 @@ class ConsistItem(models.Model):
# because the consist is not saved yet and it must be moved
# to the admin form validation via InlineFormSet.clean()
consist = self.consist
- if rolling_stock.scale != consist.scale:
+ # Scale must match, but allow loads of any scale
+ if rolling_stock.scale != consist.scale and not self.load:
raise ValidationError(
"The rolling stock and consist must be of the same scale."
)
+ if self.load and rolling_stock.scale.ratio != consist.scale.ratio:
+ raise ValidationError(
+ "The load and consist must be of the same scale ratio."
+ )
if self.consist.published and not rolling_stock.published:
raise ValidationError(
"You must unpublish the the consist before using this item."
diff --git a/ram/portal/templates/consist.html b/ram/portal/templates/consist.html
index 2d18b6d..09b2e85 100644
--- a/ram/portal/templates/consist.html
+++ b/ram/portal/templates/consist.html
@@ -7,11 +7,11 @@
{{ t.name }}{# new line is required #}
{% endfor %}