mirror of
https://github.com/daniviga/django-ram.git
synced 2025-08-04 13:17:50 +02:00
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:
@@ -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]
|
||||
|
36
ram/roster/migrations/0030_rollingstock_price.py
Normal file
36
ram/roster/migrations/0030_rollingstock_price.py
Normal 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
|
||||
),
|
||||
]
|
@@ -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
|
||||
|
@@ -28,5 +28,5 @@ class RollingStockSerializer(serializers.ModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = RollingStock
|
||||
fields = "__all__"
|
||||
exclude = ("price",)
|
||||
read_only_fields = ("creation_time", "updated_time")
|
||||
|
Reference in New Issue
Block a user