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
This commit is contained in:
2024-12-29 21:46:57 +01:00
committed by GitHub
parent 7eddd1b52b
commit 026ab06354
18 changed files with 421 additions and 15 deletions

View File

@@ -1,6 +1,13 @@
import html
from django.conf import settings
from django.contrib import admin
from django.utils.html import strip_tags
from adminsortable2.admin import SortableAdminBase, SortableInlineAdminMixin
from ram.utils import generate_csv
from portal.utils import get_site_conf
from roster.models import (
RollingClass,
RollingClassProperty,
@@ -152,8 +159,6 @@ class RollingStockAdmin(SortableAdminBase, admin.ModelAdmin):
"era",
"description",
"production_year",
"purchase_date",
"notes",
"tags",
)
},
@@ -168,6 +173,24 @@ class RollingStockAdmin(SortableAdminBase, admin.ModelAdmin):
)
},
),
(
"Purchase data",
{
"fields": (
"purchase_date",
"price",
)
},
),
(
"Notes",
{
"classes": ("collapse",),
"fields": (
"notes",
)
},
),
(
"Audit",
{
@@ -179,3 +202,65 @@ class RollingStockAdmin(SortableAdminBase, admin.ModelAdmin):
},
),
)
def get_form(self, request, obj=None, **kwargs):
form = super().get_form(request, obj, **kwargs)
form.base_fields["price"].label = "Price ({})".format(
get_site_conf().currency
)
return form
def download_csv(modeladmin, request, queryset):
header = [
"Company",
"Identifier",
"Road Number",
"Manufacturer",
"Scale",
"Item Number",
"Set",
"Era",
"Description",
"Production Year",
"Notes",
"Tags",
"Decoder Interface",
"Decoder",
"Address",
"Purchase Date",
"Price ({})".format(get_site_conf().currency),
"Properties",
]
data = []
for obj in queryset:
properties = settings.CSV_SEPARATOR_ALT.join(
"{}:{}".format(property.property.name, property.value)
for property in obj.property.all()
)
data.append([
obj.rolling_class.company.name,
obj.rolling_class.identifier,
obj.road_number,
obj.manufacturer.name,
obj.scale.scale,
obj.item_number,
obj.set,
obj.era,
html.unescape(strip_tags(obj.description)),
obj.production_year,
html.unescape(strip_tags(obj.notes)),
settings.CSV_SEPARATOR_ALT.join(
t.name for t in obj.tags.all()
),
obj.decoder_interface,
obj.decoder,
obj.address,
obj.purchase_date,
obj.price,
properties,
])
return generate_csv(header, data, "rolling_stock.csv")
download_csv.short_description = "Download selected items as CSV"
actions = [download_csv]

View File

@@ -0,0 +1,36 @@
# Generated by Django 5.1.4 on 2024-12-29 15:23
from django.db import migrations, models
def price_to_property(apps, schema_editor):
rollingstock = apps.get_model("roster", "RollingStock")
for row in rollingstock.objects.all():
prop = row.property.filter(property__name__icontains="price")
for p in prop:
try:
row.price = float(p.value)
except ValueError:
pass
row.save()
class Migration(migrations.Migration):
dependencies = [
("roster", "0029_alter_rollingstockimage_options"),
]
operations = [
migrations.AddField(
model_name="rollingstock",
name="price",
field=models.DecimalField(
blank=True, decimal_places=2, max_digits=10, null=True
),
),
migrations.RunPython(
price_to_property,
reverse_code=migrations.RunPython.noop
),
]

View File

@@ -101,6 +101,12 @@ class RollingStock(BaseModel):
)
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

View File

@@ -28,5 +28,5 @@ class RollingStockSerializer(serializers.ModelSerializer):
class Meta:
model = RollingStock
fields = "__all__"
exclude = ("price",)
read_only_fields = ("creation_time", "updated_time")