Fix filter by scale counters and add consist constrains

Still to be improved, see FIXME
This commit is contained in:
2025-05-01 23:49:22 +02:00
parent 40f42a9ee9
commit 7673f0514a
5 changed files with 103 additions and 13 deletions

View File

@@ -25,10 +25,11 @@ class ConsistItemInline(SortableInlineAdminMixin, admin.TabularInline):
class ConsistAdmin(SortableAdminBase, admin.ModelAdmin): class ConsistAdmin(SortableAdminBase, admin.ModelAdmin):
inlines = (ConsistItemInline,) inlines = (ConsistItemInline,)
readonly_fields = ( readonly_fields = (
"scale",
"creation_time", "creation_time",
"updated_time", "updated_time",
) )
list_filter = ("company__name", "era", "published") list_filter = ("company__name", "era", "scale", "published")
list_display = ("__str__",) + list_filter + ("country_flag",) list_display = ("__str__",) + list_filter + ("country_flag",)
search_fields = ("identifier",) + list_filter search_fields = ("identifier",) + list_filter
save_as = True save_as = True
@@ -49,6 +50,7 @@ class ConsistAdmin(SortableAdminBase, admin.ModelAdmin):
"consist_address", "consist_address",
"company", "company",
"era", "era",
"scale",
"description", "description",
"image", "image",
"tags", "tags",

View File

@@ -0,0 +1,42 @@
# Generated by Django 5.1.4 on 2025-05-01 09:51
import django.db.models.deletion
from django.db import migrations, models
def set_scale(apps, schema_editor):
Consist = apps.get_model("consist", "Consist")
for consist in Consist.objects.all():
try:
consist.scale = consist.consist_item.first().rolling_stock.scale
consist.save()
except AttributeError:
pass
class Migration(migrations.Migration):
dependencies = [
("consist", "0016_alter_consistitem_order"),
(
"metadata",
"0024_remove_genericdocument_tags_delete_decoderdocument_and_more",
),
]
operations = [
migrations.AddField(
model_name="consist",
name="scale",
field=models.ForeignKey(
null=True,
on_delete=django.db.models.deletion.CASCADE,
to="metadata.scale",
),
),
migrations.RunPython(
set_scale,
reverse_code=migrations.RunPython.noop
),
]

View File

@@ -7,7 +7,7 @@ from django.core.exceptions import ValidationError
from ram.models import BaseModel from ram.models import BaseModel
from ram.utils import DeduplicatedStorage from ram.utils import DeduplicatedStorage
from metadata.models import Company, Tag from metadata.models import Company, Scale, Tag
from roster.models import RollingStock from roster.models import RollingStock
@@ -26,6 +26,7 @@ class Consist(BaseModel):
blank=True, blank=True,
help_text="Era or epoch of the consist", help_text="Era or epoch of the consist",
) )
scale = models.ForeignKey(Scale, null=True, on_delete=models.CASCADE)
image = models.ImageField( image = models.ImageField(
upload_to=os.path.join("images", "consists"), upload_to=os.path.join("images", "consists"),
storage=DeduplicatedStorage, storage=DeduplicatedStorage,
@@ -81,8 +82,39 @@ class ConsistItem(models.Model):
def __str__(self): def __str__(self):
return "{0}".format(self.rolling_stock) return "{0}".format(self.rolling_stock)
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
if self.consist.scale != self.rolling_stock.scale:
self.consist.scale = self.rolling_stock.scale
self.consist.save()
def delete(self, *args, **kwargs):
super().delete(*args, **kwargs)
if not self.consist.consist_item.exists():
self.consist.scale = None
self.consist.save()
def clean(self): def clean(self):
if self.consist.published and not self.rolling_stock.published: rolling_stock = getattr(self, "rolling_stock", False)
if not rolling_stock:
return # exit if no inline are present
# FIXME this does not work when creating a new consist,
# because the consist is not saved yet and it must be moved
# to the admin form validation via InlineFormSet.clean()
consist = self.consist
items = consist.consist_item
if (
consist.pk # if we are not creating a new consist
and items.exists() # if there's at least one item
and self != items.first() # if we are not changing the first item
# if scale is different from the first item
and rolling_stock.scale != items.first().rolling_stock.scale
):
raise ValidationError(
"The rolling stock and consist must be of the same scale."
)
if self.consist.published and not rolling_stock.published:
raise ValidationError( raise ValidationError(
"You must unpublish the the consist before using this item." "You must unpublish the the consist before using this item."
) )

View File

@@ -551,16 +551,30 @@ class Scales(GetData):
item_type = "scale" item_type = "scale"
def get_data(self, request): def get_data(self, request):
return Scale.objects.annotate( return (
num_items=Count( Scale.objects.annotate(
"rollingstock", num_rollingstock=Count(
filter=Q( "rollingstock",
rollingstock__in=RollingStock.objects.get_published( filter=Q(
request.user rollingstock__in=RollingStock.objects.get_published(
) request.user
)
),
distinct=True,
), ),
), num_consists=Count(
).order_by("-ratio_int", "-tracks", "scale") "consist",
filter=Q(
consist__in=Consist.objects.get_published(
request.user
)
),
distinct=True,
),
)
.annotate(num_items=F("num_rollingstock") + F("num_consists"))
.order_by("-ratio_int", "-tracks", "scale")
)
class Types(GetData): class Types(GetData):

View File

@@ -1,4 +1,4 @@
from ram.utils import git_suffix from ram.utils import git_suffix
__version__ = "0.17.6" __version__ = "0.17.7"
__version__ += git_suffix(__file__) __version__ += git_suffix(__file__)