Add shop as a fixed property (#49)

* Add shop field (from properties)

* Update template

* Implement description in BaseModel and then consist

* Make notes internal only

* Fix a merge issue
This commit is contained in:
2025-01-27 23:16:52 +01:00
committed by GitHub
parent d16e00d66b
commit b10e1f3952
12 changed files with 52 additions and 36 deletions

View File

@@ -276,8 +276,8 @@ class CatalogAdmin(SortableAdminBase, admin.ModelAdmin):
"Publication Year", "Publication Year",
"Description", "Description",
"Tags", "Tags",
"Purchase Date",
"Shop", "Shop",
"Purchase Date",
"Price ({})".format(get_site_conf().currency), "Price ({})".format(get_site_conf().currency),
"Notes", "Notes",
"Properties", "Properties",

View File

@@ -5,8 +5,6 @@ from django.conf import settings
from django.urls import reverse from django.urls import reverse
from django_countries.fields import CountryField from django_countries.fields import CountryField
from tinymce import models as tinymce
from ram.utils import DeduplicatedStorage from ram.utils import DeduplicatedStorage
from ram.models import BaseModel, Image, Document, PropertyInstance from ram.models import BaseModel, Image, Document, PropertyInstance
from metadata.models import Scale, Manufacturer, Shop, Tag from metadata.models import Scale, Manufacturer, Shop, Tag
@@ -48,7 +46,6 @@ class BaseBook(BaseModel):
) )
number_of_pages = models.SmallIntegerField(null=True, blank=True) number_of_pages = models.SmallIntegerField(null=True, blank=True)
publication_year = models.SmallIntegerField(null=True, blank=True) publication_year = models.SmallIntegerField(null=True, blank=True)
description = tinymce.HTMLField(blank=True)
shop = models.ForeignKey( shop = models.ForeignKey(
Shop, on_delete=models.CASCADE, null=True, blank=True Shop, on_delete=models.CASCADE, null=True, blank=True
) )

View File

@@ -26,7 +26,12 @@ class BookSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Book model = Book
exclude = ("shop", "purchase_date", "price",) exclude = (
"notes",
"shop",
"purchase_date",
"price",
)
read_only_fields = ("creation_time", "updated_time") read_only_fields = ("creation_time", "updated_time")
@@ -37,5 +42,10 @@ class CatalogSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Catalog model = Catalog
exclude = ("purchase_date", "price",) exclude = (
"notes",
"shop",
"purchase_date",
"price",
)
read_only_fields = ("creation_time", "updated_time") read_only_fields = ("creation_time", "updated_time")

View File

@@ -49,12 +49,16 @@ class ConsistAdmin(SortableAdminBase, admin.ModelAdmin):
"consist_address", "consist_address",
"company", "company",
"era", "era",
"description",
"image", "image",
"notes",
"tags", "tags",
) )
}, },
), ),
(
"Notes",
{"classes": ("collapse",), "fields": ("notes",)},
),
( (
"Audit", "Audit",
{ {

View File

@@ -0,0 +1,19 @@
# Generated by Django 5.1.4 on 2025-01-27 21:15
import tinymce.models
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("consist", "0014_alter_consistitem_order"),
]
operations = [
migrations.AddField(
model_name="consist",
name="description",
field=tinymce.models.HTMLField(blank=True),
),
]

View File

@@ -21,4 +21,5 @@ class ConsistSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Consist model = Consist
fields = "__all__" exclude = ("notes",)
read_only_fields = ("creation_time", "updated_time")

View File

@@ -47,12 +47,10 @@
<nav class="nav nav-tabs d-none d-lg-flex flex-row mb-2" id="nav-tab" role="tablist"> <nav class="nav nav-tabs d-none d-lg-flex flex-row mb-2" id="nav-tab" role="tablist">
<button class="nav-link active" id="nav-summary-tab" data-bs-toggle="tab" data-bs-target="#nav-summary" type="button" role="tab" aria-controls="nav-summary" aria-selected="true">Summary</button> <button class="nav-link active" id="nav-summary-tab" data-bs-toggle="tab" data-bs-target="#nav-summary" type="button" role="tab" aria-controls="nav-summary" aria-selected="true">Summary</button>
{% if documents %}<button class="nav-link" id="nav-documents-tab" data-bs-toggle="tab" data-bs-target="#nav-documents" type="button" role="tab" aria-controls="nav-documents" aria-selected="false">Documents</button>{% endif %} {% if documents %}<button class="nav-link" id="nav-documents-tab" data-bs-toggle="tab" data-bs-target="#nav-documents" type="button" role="tab" aria-controls="nav-documents" aria-selected="false">Documents</button>{% endif %}
{% if book.notes %}<button class="nav-link" id="nav-notes-tab" data-bs-toggle="tab" data-bs-target="#nav-notes" type="button" role="tab" aria-controls="nav-notes" aria-selected="false">Notes</button>{% endif %}
</nav> </nav>
<select class="form-select d-lg-none mb-2" id="tabSelector" aria-label="Tab selector"> <select class="form-select d-lg-none mb-2" id="tabSelector" aria-label="Tab selector">
<option value="nav-summary" selected>Summary</option> <option value="nav-summary" selected>Summary</option>
{% if documents %}<option value="nav-documents">Documents</option>{% endif %} {% if documents %}<option value="nav-documents">Documents</option>{% endif %}
{% if book.notes %}<option value="nav-notes">Notes</option>{% endif %}
</select> </select>
<div class="tab-content" id="nav-tabContent"> <div class="tab-content" id="nav-tabContent">
<div class="tab-pane show active" id="nav-summary" role="tabpanel" aria-labelledby="nav-summary-tab"> <div class="tab-pane show active" id="nav-summary" role="tabpanel" aria-labelledby="nav-summary-tab">
@@ -182,9 +180,6 @@
</tbody> </tbody>
</table> </table>
</div> </div>
<div class="tab-pane" id="nav-notes" role="tabpanel" aria-labelledby="nav-notes-tab">
{{ book.notes | safe }}
</div>
</div> </div>
<div class="d-grid gap-2 d-md-flex justify-content-md-end"> <div class="d-grid gap-2 d-md-flex justify-content-md-end">
{% if request.user.is_staff %}<a class="btn btn-sm btn-outline-danger" href="{% dynamic_admin_url 'bookshelf' type book.pk %}">Edit</a>{% endif %} {% if request.user.is_staff %}<a class="btn btn-sm btn-outline-danger" href="{% dynamic_admin_url 'bookshelf' type book.pk %}">Edit</a>{% endif %}

View File

@@ -68,11 +68,9 @@
<div class="mx-auto"> <div class="mx-auto">
<nav class="nav nav-tabs d-none d-lg-flex flex-row mb-2" id="nav-tab" role="tablist"> <nav class="nav nav-tabs d-none d-lg-flex flex-row mb-2" id="nav-tab" role="tablist">
<button class="nav-link active" id="nav-summary-tab" data-bs-toggle="tab" data-bs-target="#nav-summary" type="button" role="tab" aria-controls="nav-summary" aria-selected="true">Summary</button> <button class="nav-link active" id="nav-summary-tab" data-bs-toggle="tab" data-bs-target="#nav-summary" type="button" role="tab" aria-controls="nav-summary" aria-selected="true">Summary</button>
{% if consist.notes %}<button class="nav-link" id="nav-notes-tab" data-bs-toggle="tab" data-bs-target="#nav-notes" type="button" role="tab" aria-controls="nav-notes" aria-selected="false">Notes</button>{% endif %}
</nav> </nav>
<select class="form-select d-lg-none mb-2" id="tabSelector" aria-label="Tab selector"> <select class="form-select d-lg-none mb-2" id="tabSelector" aria-label="Tab selector">
<option value="nav-summary" selected>Summary</option> <option value="nav-summary" selected>Summary</option>
{% if consist.notes %}<option value="nav-notes">Notes</option>{% endif %}
</select> </select>
<div class="tab-content" id="nav-tabContent"> <div class="tab-content" id="nav-tabContent">
<div class="tab-pane show active" id="nav-summary" role="tabpanel" aria-labelledby="nav-summary-tab"> <div class="tab-pane show active" id="nav-summary" role="tabpanel" aria-labelledby="nav-summary-tab">
@@ -103,6 +101,12 @@
<th scope="row">Era</th> <th scope="row">Era</th>
<td>{{ consist.era }}</td> <td>{{ consist.era }}</td>
</tr> </tr>
{% if consist.description %}
<tr>
<th scope="row">Description</th>
<td>{{ consist.description | safe }}</td>
</tr>
{% endif %}
<tr> <tr>
<th scope="row">Length</th> <th scope="row">Length</th>
<td>{{ data | length }}</td> <td>{{ data | length }}</td>
@@ -110,20 +114,6 @@
</tbody> </tbody>
</table> </table>
</div> </div>
<div class="tab-pane" id="nav-notes" role="tabpanel" aria-labelledby="nav-notes-tab">
<table class="table">
<thead>
<tr>
<th scope="row">Notes</th>
</tr>
</thead>
<tbody class="table-group-divider">
<tr>
<td>{{ consist.notes | safe }}</td>
</tr>
</tbody>
</table>
</div>
</div> </div>
<div class="d-grid gap-2 d-md-flex justify-content-md-end"> <div class="d-grid gap-2 d-md-flex justify-content-md-end">
{% if request.user.is_staff %}<a class="btn btn-sm btn-outline-danger" href="{% url 'admin:consist_consist_change' consist.pk %}">Edit</a>{% endif %} {% if request.user.is_staff %}<a class="btn btn-sm btn-outline-danger" href="{% url 'admin:consist_consist_change' consist.pk %}">Edit</a>{% endif %}

View File

@@ -51,7 +51,6 @@
{% if rolling_stock.decoder %}<button class="nav-link" id="nav-dcc-tab" data-bs-toggle="tab" data-bs-target="#nav-dcc" type="button" role="tab" aria-controls="nav-dcc" aria-selected="false">DCC</button>{% endif %} {% if rolling_stock.decoder %}<button class="nav-link" id="nav-dcc-tab" data-bs-toggle="tab" data-bs-target="#nav-dcc" type="button" role="tab" aria-controls="nav-dcc" aria-selected="false">DCC</button>{% endif %}
{% if documents or decoder_documents %}<button class="nav-link" id="nav-documents-tab" data-bs-toggle="tab" data-bs-target="#nav-documents" type="button" role="tab" aria-controls="nav-documents" aria-selected="false">Documents</button>{% endif %} {% if documents or decoder_documents %}<button class="nav-link" id="nav-documents-tab" data-bs-toggle="tab" data-bs-target="#nav-documents" type="button" role="tab" aria-controls="nav-documents" aria-selected="false">Documents</button>{% endif %}
{% if journal %}<button class="nav-link" id="nav-journal-tab" data-bs-toggle="tab" data-bs-target="#nav-journal" type="button" role="tab" aria-controls="nav-journal" aria-selected="false">Journal</button>{% endif %} {% if journal %}<button class="nav-link" id="nav-journal-tab" data-bs-toggle="tab" data-bs-target="#nav-journal" type="button" role="tab" aria-controls="nav-journal" aria-selected="false">Journal</button>{% endif %}
{% if rolling_stock.notes %}<button class="nav-link" id="nav-notes-tab" data-bs-toggle="tab" data-bs-target="#nav-notes" type="button" role="tab" aria-controls="nav-notes" aria-selected="false">Notes</button>{% endif %}
{% if set %}<button class="nav-link" id="nav-set-tab" data-bs-toggle="tab" data-bs-target="#nav-set" type="button" role="tab" aria-controls="nav-set" aria-selected="false">Set</button>{% endif %} {% if set %}<button class="nav-link" id="nav-set-tab" data-bs-toggle="tab" data-bs-target="#nav-set" type="button" role="tab" aria-controls="nav-set" aria-selected="false">Set</button>{% endif %}
{% if consists %}<button class="nav-link" id="nav-consists-tab" data-bs-toggle="tab" data-bs-target="#nav-consists" type="button" role="tab" aria-controls="nav-consists" aria-selected="false">Consists</button>{% endif %} {% if consists %}<button class="nav-link" id="nav-consists-tab" data-bs-toggle="tab" data-bs-target="#nav-consists" type="button" role="tab" aria-controls="nav-consists" aria-selected="false">Consists</button>{% endif %}
</nav> </nav>
@@ -63,7 +62,6 @@
{% if rolling_stock.decoder %}<option value="nav-dcc">DCC</option>{% endif %} {% if rolling_stock.decoder %}<option value="nav-dcc">DCC</option>{% endif %}
{% if documents or decoder_documents %}<option value="nav-documents">Documents</option>{% endif %} {% if documents or decoder_documents %}<option value="nav-documents">Documents</option>{% endif %}
{% if journal %}<option value="nav-journal">Journal</option>{% endif %} {% if journal %}<option value="nav-journal">Journal</option>{% endif %}
{% if rolling_stock.notes %}<option value="nav-notes">Notes</option>{% endif %}
{% if set %}<option value="nav-set">Set</option>{% endif %} {% if set %}<option value="nav-set">Set</option>{% endif %}
{% if consists %}<option value="nav-consists">Consists</option>{% endif %} {% if consists %}<option value="nav-consists">Consists</option>{% endif %}
</select> </select>
@@ -427,9 +425,6 @@
</tbody> </tbody>
</table> </table>
</div> </div>
<div class="tab-pane" id="nav-notes" role="tabpanel" aria-labelledby="nav-notes-tab">
{{ rolling_stock.notes | safe }}
</div>
<div class="tab-pane" id="nav-set" role="tabpanel" aria-labelledby="nav-set-tab"> <div class="tab-pane" id="nav-set" role="tabpanel" aria-labelledby="nav-set-tab">
<div class="row row-cols-1 row-cols-md-2 row-cols-lg-3 g-3 mb-3"> <div class="row row-cols-1 row-cols-md-2 row-cols-lg-3 g-3 mb-3">
{% for d in set %} {% for d in set %}

View File

@@ -11,6 +11,7 @@ from ram.managers import PublicManager
class BaseModel(models.Model): class BaseModel(models.Model):
uuid = models.UUIDField(primary_key=True, default=uuid4, editable=False) uuid = models.UUIDField(primary_key=True, default=uuid4, editable=False)
description = tinymce.HTMLField(blank=True)
notes = tinymce.HTMLField(blank=True) notes = tinymce.HTMLField(blank=True)
creation_time = models.DateTimeField(auto_now_add=True) creation_time = models.DateTimeField(auto_now_add=True)
updated_time = models.DateTimeField(auto_now=True) updated_time = models.DateTimeField(auto_now=True)

View File

@@ -113,7 +113,6 @@ class RollingStock(BaseModel):
null=True, null=True,
blank=True, blank=True,
) )
description = tinymce.HTMLField(blank=True)
tags = models.ManyToManyField( tags = models.ManyToManyField(
Tag, related_name="rolling_stock", blank=True Tag, related_name="rolling_stock", blank=True
) )

View File

@@ -29,5 +29,10 @@ class RollingStockSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = RollingStock model = RollingStock
exclude = ("shop", "purchase_date", "price",) exclude = (
"notes",
"shop",
"purchase_date",
"price",
)
read_only_fields = ("creation_time", "updated_time") read_only_fields = ("creation_time", "updated_time")