mirror of
https://github.com/daniviga/django-ram.git
synced 2025-08-04 05:07:50 +02:00
Fix filter by scale counters and add consist constrains
Still to be improved, see FIXME
This commit is contained in:
@@ -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",
|
||||||
|
42
ram/consist/migrations/0017_consist_scale.py
Normal file
42
ram/consist/migrations/0017_consist_scale.py
Normal 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
|
||||||
|
),
|
||||||
|
]
|
@@ -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."
|
||||||
)
|
)
|
||||||
|
@@ -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):
|
||||||
|
@@ -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__)
|
||||||
|
Reference in New Issue
Block a user