from django.contrib import admin
from django.utils.html import format_html
from django.db.models import Avg
from .models import Ride, RollerCoasterStats
class RollerCoasterStatsInline(admin.StackedInline):
model = RollerCoasterStats
can_delete = False
extra = 0
fieldsets = (
('Basic Stats', {
'fields': (
('height_ft', 'length_ft'),
('speed_mph', 'inversions'),
'ride_time_seconds'
)
}),
('Track Details', {
'fields': (
'track_type',
'launch_type'
)
}),
('Train Configuration', {
'fields': (
'train_style',
('trains_count', 'cars_per_train', 'seats_per_car')
)
}),
)
@admin.register(Ride)
class RideAdmin(admin.ModelAdmin):
list_display = ('id', 'name', 'park', 'category', 'get_status', 'manufacturer', 'opening_date', 'get_avg_rating')
list_filter = ('status', 'category', 'manufacturer', 'park')
search_fields = ('name', 'park__name', 'manufacturer__name', 'description')
prepopulated_fields = {'slug': ('name',)}
inlines = [RollerCoasterStatsInline]
readonly_fields = ('id', 'created_at', 'updated_at')
actions = ['mark_as_operating', 'mark_as_closed', 'mark_as_under_maintenance', 'mark_as_removed']
fieldsets = (
('Basic Information', {
'fields': (
'name',
'slug',
'description',
'park',
'park_area'
)
}),
('Ride Details', {
'fields': (
'category',
'manufacturer',
'model_name',
'status'
)
}),
('Dates', {
'fields': (
'opening_date',
'closing_date',
'status_since'
)
}),
('Requirements', {
'fields': (
'min_height_in',
'max_height_in',
'accessibility_options'
)
}),
('Capacity', {
'fields': (
'capacity_per_hour',
'ride_duration_seconds'
)
}),
('Metadata', {
'fields': ('id', 'created_at', 'updated_at'),
'classes': ('collapse',)
}),
)
def get_status(self, obj):
status_colors = {
'OPERATING': 'green',
'CLOSED_TEMP': 'orange',
'CLOSED_PERM': 'red',
'UNDER_CONSTRUCTION': 'blue',
'DEMOLISHED': 'grey',
'RELOCATED': 'purple'
}
return format_html(
'{}',
status_colors.get(obj.status, 'black'),
obj.get_status_display()
)
get_status.short_description = 'Status'
def get_avg_rating(self, obj):
avg = obj.reviews.filter(is_published=True).aggregate(avg_rating=Avg('rating'))['avg_rating']
if avg:
rating_str = '{:.1f}'.format(float(avg))
return format_html(
'★ {}',
rating_str
)
return '-'
get_avg_rating.short_description = 'Rating'
def mark_as_operating(self, request, queryset):
queryset.update(status='OPERATING')
mark_as_operating.short_description = "Mark selected rides as operating"
def mark_as_closed(self, request, queryset):
queryset.update(status='CLOSED_TEMP')
mark_as_closed.short_description = "Mark selected rides as temporarily closed"
def mark_as_under_maintenance(self, request, queryset):
queryset.update(status='CLOSED_TEMP')
mark_as_under_maintenance.short_description = "Mark selected rides as under maintenance"
def mark_as_removed(self, request, queryset):
queryset.update(status='DEMOLISHED')
mark_as_removed.short_description = "Mark selected rides as demolished"
@admin.register(RollerCoasterStats)
class RollerCoasterStatsAdmin(admin.ModelAdmin):
list_display = ('ride', 'height_ft', 'length_ft', 'speed_mph', 'inversions', 'get_capacity')
list_filter = ('launch_type', 'track_type', 'train_style')
search_fields = ('ride__name', 'track_type')
readonly_fields = ('id', 'ride')
fieldsets = (
('Basic Stats', {
'fields': (
'id',
'ride',
('height_ft', 'length_ft'),
('speed_mph', 'inversions'),
'ride_time_seconds'
)
}),
('Track Details', {
'fields': (
'track_type',
'launch_type'
)
}),
('Train Configuration', {
'fields': (
'train_style',
('trains_count', 'cars_per_train', 'seats_per_car')
)
}),
)
def get_capacity(self, obj):
if obj.trains_count and obj.cars_per_train and obj.seats_per_car:
capacity = obj.trains_count * obj.cars_per_train * obj.seats_per_car
return format_html(
'{} seats total',
str(capacity)
)
return '-'
get_capacity.short_description = 'Total Capacity'