Files
django-ram/ram/roster/models.py
Daniele Viganò 026ab06354 Add a CSV export functionality in admin and add price fields (#41)
* Implement an action do download data in csv
* Refactor CSV download
* Move price to main models and add csv to bookshelf
* Update template and API
* Small refactoring
2024-12-29 21:46:57 +01:00

224 lines
6.0 KiB
Python

import os
import re
import shutil
from django.db import models
from django.urls import reverse
from django.conf import settings
from django.dispatch import receiver
from tinymce import models as tinymce
from ram.models import BaseModel, Document, Image, PropertyInstance
from ram.utils import DeduplicatedStorage
from ram.managers import PublicManager
from metadata.models import (
Scale,
Manufacturer,
Decoder,
Company,
Tag,
RollingStockType,
)
class RollingClass(models.Model):
identifier = models.CharField(max_length=128, unique=False)
type = models.ForeignKey(RollingStockType, on_delete=models.CASCADE)
company = models.ForeignKey(Company, on_delete=models.CASCADE)
description = tinymce.HTMLField(blank=True)
manufacturer = models.ForeignKey(
Manufacturer,
on_delete=models.CASCADE,
null=True,
blank=True,
limit_choices_to={"category": "real"},
)
class Meta:
ordering = ["company", "identifier"]
verbose_name = "Class"
verbose_name_plural = "Classes"
def __str__(self):
return "{0} {1}".format(self.company, self.identifier)
class RollingClassProperty(PropertyInstance):
rolling_class = models.ForeignKey(
RollingClass,
on_delete=models.CASCADE,
null=False,
blank=False,
related_name="property",
verbose_name="Class",
)
class RollingStock(BaseModel):
rolling_class = models.ForeignKey(
RollingClass,
on_delete=models.CASCADE,
null=False,
blank=False,
related_name="rolling_class",
verbose_name="Class",
)
road_number = models.CharField(max_length=128, unique=False)
road_number_int = models.PositiveSmallIntegerField(default=0, unique=False)
manufacturer = models.ForeignKey(
Manufacturer,
on_delete=models.CASCADE,
null=True,
blank=True,
limit_choices_to={"category": "model"},
)
scale = models.ForeignKey(Scale, on_delete=models.CASCADE)
item_number = models.CharField(
max_length=32,
blank=True,
help_text="Catalog item number or code",
)
item_number_slug = models.CharField(
max_length=32,
blank=True,
editable=False
)
set = models.BooleanField(
default=False,
help_text="Part of a set",
)
decoder_interface = models.PositiveSmallIntegerField(
choices=settings.DECODER_INTERFACES, null=True, blank=True
)
decoder = models.ForeignKey(
Decoder, on_delete=models.CASCADE, null=True, blank=True
)
address = models.SmallIntegerField(default=None, null=True, blank=True)
era = models.CharField(
max_length=32,
blank=True,
help_text="Era or epoch of the model",
)
production_year = models.SmallIntegerField(null=True, blank=True)
purchase_date = models.DateField(null=True, blank=True)
price = models.DecimalField(
max_digits=10,
decimal_places=2,
null=True,
blank=True,
)
description = tinymce.HTMLField(blank=True)
tags = models.ManyToManyField(
Tag, related_name="rolling_stock", blank=True
)
class Meta:
ordering = ["rolling_class", "road_number_int"]
verbose_name_plural = "Rolling stock"
def __str__(self):
return "{0} {1}".format(self.rolling_class, self.road_number)
def get_absolute_url(self):
return reverse("rolling_stock", kwargs={"uuid": self.uuid})
def preview(self):
return self.image.first().image_thumbnail(350)
def country(self):
return str(self.rolling_class.company.country)
def company(self):
return str(self.rolling_class.company)
def delete(self, *args, **kwargs):
shutil.rmtree(
os.path.join(
settings.MEDIA_ROOT, "images", "rollingstock", str(self.uuid)
),
ignore_errors=True
)
super(RollingStock, self).delete(*args, **kwargs)
@receiver(models.signals.pre_save, sender=RollingStock)
def pre_save_running_number(sender, instance, *args, **kwargs):
try:
instance.road_number_int = int(
re.findall(r"\d+", instance.road_number)[0]
)
except IndexError:
pass
class RollingStockDocument(Document):
rolling_stock = models.ForeignKey(
RollingStock, on_delete=models.CASCADE, related_name="document"
)
class Meta(object):
unique_together = ("rolling_stock", "file")
def rolling_stock_image_upload(instance, filename):
return os.path.join(
"images",
"rollingstock",
str(instance.rolling_stock.uuid),
filename
)
class RollingStockImage(Image):
rolling_stock = models.ForeignKey(
RollingStock, on_delete=models.CASCADE, related_name="image"
)
image = models.ImageField(
upload_to=rolling_stock_image_upload,
storage=DeduplicatedStorage,
)
class RollingStockProperty(PropertyInstance):
rolling_stock = models.ForeignKey(
RollingStock,
on_delete=models.CASCADE,
related_name="property",
null=False,
blank=False,
)
class RollingStockJournal(models.Model):
rolling_stock = models.ForeignKey(
RollingStock,
on_delete=models.CASCADE,
related_name="journal",
null=False,
blank=False,
)
date = models.DateField()
log = tinymce.HTMLField()
private = models.BooleanField(
default=False,
help_text="Journal log will be visible only to logged users",
)
creation_time = models.DateTimeField(auto_now_add=True)
updated_time = models.DateTimeField(auto_now=True)
def __str__(self):
return "{0} - {1}".format(self.rolling_stock, self.date)
class Meta:
ordering = ["date", "rolling_stock"]
objects = PublicManager()
# @receiver(models.signals.post_delete, sender=Cab)
# def post_save_image(sender, instance, *args, **kwargs):
# try:
# instance.image.delete(save=False)
# except Exception:
# pass