mirror of
https://github.com/daniviga/django-ram.git
synced 2025-08-04 13:17:50 +02:00
124 lines
3.5 KiB
Python
124 lines
3.5 KiB
Python
import os
|
|
|
|
from django.db import models
|
|
from django.urls import reverse
|
|
from django.dispatch import receiver
|
|
from django.core.exceptions import ValidationError
|
|
|
|
from ram.models import BaseModel
|
|
from ram.utils import DeduplicatedStorage
|
|
from metadata.models import Company, Tag
|
|
from roster.models import RollingStock
|
|
|
|
|
|
class Consist(BaseModel):
|
|
identifier = models.CharField(max_length=128, unique=False)
|
|
tags = models.ManyToManyField(Tag, related_name="consist", blank=True)
|
|
consist_address = models.SmallIntegerField(
|
|
default=None,
|
|
null=True,
|
|
blank=True,
|
|
help_text="DCC consist address if enabled",
|
|
)
|
|
company = models.ForeignKey(Company, on_delete=models.CASCADE)
|
|
era = models.CharField(
|
|
max_length=32,
|
|
blank=True,
|
|
help_text="Era or epoch of the consist",
|
|
)
|
|
image = models.ImageField(
|
|
upload_to=os.path.join("images", "consists"),
|
|
storage=DeduplicatedStorage,
|
|
null=True,
|
|
blank=True,
|
|
)
|
|
|
|
def __str__(self):
|
|
return "{0} {1}".format(self.company, self.identifier)
|
|
|
|
def get_absolute_url(self):
|
|
return reverse("consist", kwargs={"uuid": self.uuid})
|
|
|
|
@property
|
|
def length(self):
|
|
return self.consist_item.count()
|
|
|
|
def get_type_count(self):
|
|
return self.consist_item.annotate(
|
|
type=models.F("rolling_stock__rolling_class__type__type")
|
|
).values(
|
|
"type"
|
|
).annotate(
|
|
count=models.Count("rolling_stock"),
|
|
category=models.F("rolling_stock__rolling_class__type__category"),
|
|
order=models.Max("order"),
|
|
).order_by("order")
|
|
|
|
@property
|
|
def country(self):
|
|
return self.company.country
|
|
|
|
class Meta:
|
|
ordering = ["company", "-creation_time"]
|
|
|
|
|
|
class ConsistItem(models.Model):
|
|
consist = models.ForeignKey(
|
|
Consist, on_delete=models.CASCADE, related_name="consist_item"
|
|
)
|
|
rolling_stock = models.ForeignKey(RollingStock, on_delete=models.CASCADE)
|
|
order = models.PositiveIntegerField(blank=False, null=False)
|
|
|
|
class Meta:
|
|
ordering = ["order"]
|
|
constraints = [
|
|
models.UniqueConstraint(
|
|
fields=["consist", "rolling_stock"],
|
|
name="one_stock_per_consist"
|
|
)
|
|
]
|
|
|
|
def __str__(self):
|
|
return "{0}".format(self.rolling_stock)
|
|
|
|
def clean(self):
|
|
if self.consist.published and not self.rolling_stock.published:
|
|
raise ValidationError(
|
|
"You must unpublish the the consist before using this item."
|
|
)
|
|
|
|
def published(self):
|
|
return self.rolling_stock.published
|
|
published.boolean = True
|
|
|
|
def preview(self):
|
|
return self.rolling_stock.image.first().image_thumbnail(100)
|
|
|
|
@property
|
|
def type(self):
|
|
return self.rolling_stock.rolling_class.type
|
|
|
|
@property
|
|
def address(self):
|
|
return self.rolling_stock.address
|
|
|
|
@property
|
|
def company(self):
|
|
return self.rolling_stock.company
|
|
|
|
@property
|
|
def era(self):
|
|
return self.rolling_stock.era
|
|
|
|
|
|
# Unpublish any consist that contains an unpublished rolling stock
|
|
# this signal is called after a rolling stock is saved
|
|
# it is hosted here to avoid circular imports
|
|
@receiver(models.signals.post_save, sender=RollingStock)
|
|
def post_save_unpublish_consist(sender, instance, *args, **kwargs):
|
|
if not instance.published:
|
|
consists = Consist.objects.filter(consist_item__rolling_stock=instance)
|
|
for consist in consists:
|
|
consist.published = False
|
|
consist.save()
|