Compare commits

...

2 Commits

5 changed files with 60 additions and 55 deletions

View File

@@ -2,7 +2,12 @@ import html
from django.conf import settings from django.conf import settings
from django.contrib import admin from django.contrib import admin
from django.utils.html import format_html, format_html_join, strip_tags from django.utils.html import (
format_html,
format_html_join,
strip_tags,
mark_safe,
)
from adminsortable2.admin import SortableAdminBase, SortableInlineAdminMixin from adminsortable2.admin import SortableAdminBase, SortableInlineAdminMixin
from ram.admin import publish, unpublish from ram.admin import publish, unpublish
@@ -149,7 +154,7 @@ class BookAdmin(SortableAdminBase, admin.ModelAdmin):
def invoices(self, obj): def invoices(self, obj):
if obj.invoice.exists(): if obj.invoice.exists():
html = format_html_join( html = format_html_join(
"<br>", mark_safe("<br>"),
'<a href="{}" target="_blank">{}</a>', '<a href="{}" target="_blank">{}</a>',
((i.file.url, i) for i in obj.invoice.all()), ((i.file.url, i) for i in obj.invoice.all()),
) )
@@ -317,7 +322,7 @@ class CatalogAdmin(SortableAdminBase, admin.ModelAdmin):
def invoices(self, obj): def invoices(self, obj):
if obj.invoice.exists(): if obj.invoice.exists():
html = format_html_join( html = format_html_join(
"<br>", mark_safe("<br>"),
'<a href="{}" target="_blank">{}</a>', '<a href="{}" target="_blank">{}</a>',
((i.file.url, i) for i in obj.invoice.all()), ((i.file.url, i) for i in obj.invoice.all()),
) )

View File

@@ -17,15 +17,13 @@ def dcc(object):
f'<i class="bi bi-dice-6"></i></abbr>' f'<i class="bi bi-dice-6"></i></abbr>'
) )
if object.decoder: if object.decoder:
decoder = mark_safe(f'<abbr title="{object.decoder}">')
if object.decoder.sound: if object.decoder.sound:
decoder = mark_safe( decoder += mark_safe(
f'<abbr title="{object.decoder}">'
'<i class="bi bi-volume-up-fill"></i></abbr>' '<i class="bi bi-volume-up-fill"></i></abbr>'
) )
else: else:
decoder = mark_safe( decoder += mark_safe(
f'<abbr title="{object.decoder}'
f'({object.get_decoder_interface()})">'
'<i class="bi bi-cpu-fill"></i></abbr>' '<i class="bi bi-cpu-fill"></i></abbr>'
) )
if decoder: if decoder:

View File

@@ -1,17 +1,7 @@
""" """
Django settings for ram project. Django settings for ram project.
Generated by 'django-admin startproject' using Django 4.0.
For more information on this file, see
https://docs.djangoproject.com/en/4.0/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/4.0/ref/settings/
""" """
import os
import time
from pathlib import Path from pathlib import Path
# Build paths inside the project like this: BASE_DIR / 'subdir'. # Build paths inside the project like this: BASE_DIR / 'subdir'.
@@ -23,7 +13,7 @@ STORAGE_DIR = BASE_DIR / "storage"
# SECURITY WARNING: keep the secret key used in production secret! # SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = ( SECRET_KEY = (
"django-insecure-1fgtf05rwp0qp05@ef@a7%x#o+t6vk6063py=vhdmut0j!8s4u" "django-ram-insecure-Chang3m3-1n-Pr0duct10n!"
) )
# SECURITY WARNING: don't run with debug turned on in production! # SECURITY WARNING: don't run with debug turned on in production!
@@ -31,9 +21,6 @@ DEBUG = True
ALLOWED_HOSTS = ["*"] ALLOWED_HOSTS = ["*"]
# Application definition
INSTALLED_APPS = [ INSTALLED_APPS = [
"django.contrib.admin", "django.contrib.admin",
"django.contrib.auth", "django.contrib.auth",
@@ -87,10 +74,6 @@ TEMPLATES = [
WSGI_APPLICATION = "ram.wsgi.application" WSGI_APPLICATION = "ram.wsgi.application"
# Database
# https://docs.djangoproject.com/en/4.0/ref/settings/#databases
DATABASES = { DATABASES = {
"default": { "default": {
"ENGINE": "django.db.backends.sqlite3", "ENGINE": "django.db.backends.sqlite3",
@@ -98,54 +81,38 @@ DATABASES = {
} }
} }
# Password validation
# https://docs.djangoproject.com/en/4.0/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [ AUTH_PASSWORD_VALIDATORS = [
{ {
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", # noqa: E501
}, },
{ {
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", # noqa: E501
}, },
{ {
"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator", "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator", # noqa: E501
}, },
{ {
"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator", "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator", # noqa: E501
}, },
] ]
# Internationalization
# https://docs.djangoproject.com/en/4.0/topics/i18n/
LANGUAGE_CODE = "en-us" LANGUAGE_CODE = "en-us"
TIME_ZONE = "UTC" TIME_ZONE = "UTC"
USE_I18N = True USE_I18N = True
USE_TZ = True USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.0/howto/static-files/
STATIC_URL = "static/" STATIC_URL = "static/"
# Default primary key field type
# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
MEDIA_URL = "media/" MEDIA_URL = "media/"
MEDIA_ROOT = STORAGE_DIR / "media" MEDIA_ROOT = STORAGE_DIR / "media"
# django-ram REST API settings
REST_ENABLED = False # Set to True to enable the REST API REST_ENABLED = False # Set to True to enable the REST API
REST_FRAMEWORK = { REST_FRAMEWORK = {
"DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.LimitOffsetPagination", "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.LimitOffsetPagination", # noqa: E501
"PAGE_SIZE": 5, "PAGE_SIZE": 5,
} }
@@ -171,7 +138,7 @@ COUNTRIES_OVERRIDE = {
"XX": "None", "XX": "None",
} }
SITE_NAME = "Railroad Assets Manger" SITE_NAME = "Railroad Assets Manager"
# Image used on cards without a custom image uploaded. # Image used on cards without a custom image uploaded.
# The file must be placed in the root of the 'static' folder # The file must be placed in the root of the 'static' folder
@@ -184,9 +151,10 @@ DECODER_INTERFACES = [
(0, "Built-in"), (0, "Built-in"),
(1, "NEM651"), (1, "NEM651"),
(2, "NEM652"), (2, "NEM652"),
(3, "PluX"), (3, "NEM658 (Plux22)"),
(4, "21MTC"), (4, "NEM660 (21MTC)"),
(5, "Next18/Next18S"), (5, "NEM662 (Next18/Next18S)"),
(3, "NEM658 (Plux16)"),
] ]
MANUFACTURER_TYPES = [ MANUFACTURER_TYPES = [

View File

@@ -2,8 +2,12 @@ import html
from django.conf import settings from django.conf import settings
from django.contrib import admin from django.contrib import admin
from django.utils.html import format_html, format_html_join, strip_tags from django.utils.html import (
format_html,
format_html_join,
strip_tags,
mark_safe,
)
from adminsortable2.admin import SortableAdminBase, SortableInlineAdminMixin from adminsortable2.admin import SortableAdminBase, SortableInlineAdminMixin
from ram.utils import generate_csv from ram.utils import generate_csv
@@ -229,7 +233,7 @@ class RollingStockAdmin(SortableAdminBase, admin.ModelAdmin):
def invoices(self, obj): def invoices(self, obj):
if obj.invoice.exists(): if obj.invoice.exists():
html = format_html_join( html = format_html_join(
"<br>", mark_safe("<br>"),
'<a href="{}" target="_blank">{}</a>', '<a href="{}" target="_blank">{}</a>',
((i.file.url, i) for i in obj.invoice.all()), ((i.file.url, i) for i in obj.invoice.all()),
) )

View File

@@ -0,0 +1,30 @@
# Generated by Django 6.0 on 2026-01-08 11:14
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("roster", "0039_rollingstock_featured"),
]
operations = [
migrations.AlterField(
model_name="rollingstock",
name="decoder_interface",
field=models.PositiveSmallIntegerField(
blank=True,
choices=[
(0, "Built-in"),
(1, "NEM651"),
(2, "NEM652"),
(3, "NEM658 (Plux22)"),
(4, "NEM660 (21MTC)"),
(5, "NEM662 (Next18/Next18S)"),
(3, "NEM658 (Plux16)"),
],
null=True,
),
),
]