mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 13:31:08 -05:00
404 lines
10 KiB
Python
404 lines
10 KiB
Python
from django.contrib import admin
|
|
# from django.contrib.gis.admin import GISModelAdmin # Disabled temporarily for setup
|
|
from django.utils.html import format_html
|
|
import pghistory.models
|
|
from .models import (
|
|
Park,
|
|
ParkArea,
|
|
ParkLocation,
|
|
Company,
|
|
CompanyHeadquarters,
|
|
ParkReview,
|
|
)
|
|
|
|
|
|
class ParkLocationInline(admin.StackedInline):
|
|
"""Inline admin for ParkLocation"""
|
|
|
|
model = ParkLocation
|
|
extra = 0
|
|
fields = (
|
|
("city", "state", "country"),
|
|
"street_address",
|
|
"postal_code",
|
|
"point",
|
|
("highway_exit", "best_arrival_time"),
|
|
"parking_notes",
|
|
"seasonal_notes",
|
|
("osm_id", "osm_type"),
|
|
)
|
|
|
|
|
|
class ParkLocationAdmin(admin.ModelAdmin): # GISModelAdmin disabled for setup
|
|
"""Admin for standalone ParkLocation management"""
|
|
|
|
list_display = (
|
|
"park",
|
|
"city",
|
|
"state",
|
|
"country",
|
|
"latitude",
|
|
"longitude",
|
|
)
|
|
list_filter = ("country", "state")
|
|
search_fields = (
|
|
"park__name",
|
|
"city",
|
|
"state",
|
|
"country",
|
|
"street_address",
|
|
)
|
|
readonly_fields = ("latitude", "longitude", "coordinates")
|
|
fieldsets = (
|
|
("Park", {"fields": ("park",)}),
|
|
(
|
|
"Address",
|
|
{
|
|
"fields": (
|
|
"street_address",
|
|
"city",
|
|
"state",
|
|
"country",
|
|
"postal_code",
|
|
)
|
|
},
|
|
),
|
|
(
|
|
"Geographic Coordinates",
|
|
{
|
|
"fields": ("point", "latitude", "longitude", "coordinates"),
|
|
"description": "Set coordinates by clicking on the map or entering latitude/longitude",
|
|
},
|
|
),
|
|
(
|
|
"Travel Information",
|
|
{
|
|
"fields": (
|
|
"highway_exit",
|
|
"best_arrival_time",
|
|
"parking_notes",
|
|
"seasonal_notes",
|
|
),
|
|
"classes": ("collapse",),
|
|
},
|
|
),
|
|
(
|
|
"OpenStreetMap Integration",
|
|
{"fields": ("osm_id", "osm_type"), "classes": ("collapse",)},
|
|
),
|
|
)
|
|
|
|
@admin.display(description="Latitude")
|
|
def latitude(self, obj):
|
|
return obj.latitude
|
|
|
|
@admin.display(description="Longitude")
|
|
def longitude(self, obj):
|
|
return obj.longitude
|
|
|
|
|
|
class ParkAdmin(admin.ModelAdmin):
|
|
list_display = (
|
|
"name",
|
|
"formatted_location",
|
|
"status",
|
|
"operator",
|
|
"property_owner",
|
|
"created_at",
|
|
"updated_at",
|
|
)
|
|
list_filter = ("status", "location__country", "location__state")
|
|
search_fields = (
|
|
"name",
|
|
"description",
|
|
"location__city",
|
|
"location__state",
|
|
"location__country",
|
|
)
|
|
readonly_fields = ("created_at", "updated_at")
|
|
prepopulated_fields = {"slug": ("name",)}
|
|
inlines = [ParkLocationInline]
|
|
|
|
@admin.display(description="Location")
|
|
def formatted_location(self, obj):
|
|
"""Display formatted location string"""
|
|
return obj.formatted_location
|
|
|
|
|
|
class ParkAreaAdmin(admin.ModelAdmin):
|
|
list_display = ("name", "park", "created_at", "updated_at")
|
|
list_filter = ("park",)
|
|
search_fields = ("name", "description", "park__name")
|
|
readonly_fields = ("created_at", "updated_at")
|
|
prepopulated_fields = {"slug": ("name",)}
|
|
|
|
|
|
class CompanyHeadquartersInline(admin.StackedInline):
|
|
"""Inline admin for CompanyHeadquarters"""
|
|
|
|
model = CompanyHeadquarters
|
|
extra = 0
|
|
fields = (
|
|
("city", "state_province", "country"),
|
|
"street_address",
|
|
"postal_code",
|
|
"mailing_address",
|
|
)
|
|
|
|
|
|
class CompanyHeadquartersAdmin(admin.ModelAdmin):
|
|
"""Admin for standalone CompanyHeadquarters management"""
|
|
|
|
list_display = (
|
|
"company",
|
|
"location_display",
|
|
"city",
|
|
"country",
|
|
"created_at",
|
|
)
|
|
list_filter = ("country", "state_province")
|
|
search_fields = (
|
|
"company__name",
|
|
"city",
|
|
"state_province",
|
|
"country",
|
|
"street_address",
|
|
)
|
|
readonly_fields = ("created_at", "updated_at")
|
|
fieldsets = (
|
|
("Company", {"fields": ("company",)}),
|
|
(
|
|
"Address",
|
|
{
|
|
"fields": (
|
|
"street_address",
|
|
"city",
|
|
"state_province",
|
|
"country",
|
|
"postal_code",
|
|
)
|
|
},
|
|
),
|
|
(
|
|
"Additional Information",
|
|
{"fields": ("mailing_address",), "classes": ("collapse",)},
|
|
),
|
|
(
|
|
"Metadata",
|
|
{"fields": ("created_at", "updated_at"), "classes": ("collapse",)},
|
|
),
|
|
)
|
|
|
|
|
|
class CompanyAdmin(admin.ModelAdmin):
|
|
"""Enhanced Company admin with headquarters inline"""
|
|
|
|
list_display = (
|
|
"name",
|
|
"roles_display",
|
|
"headquarters_location",
|
|
"website",
|
|
"founded_year",
|
|
)
|
|
list_filter = ("roles",)
|
|
search_fields = ("name", "description")
|
|
readonly_fields = ("created_at", "updated_at")
|
|
prepopulated_fields = {"slug": ("name",)}
|
|
inlines = [CompanyHeadquartersInline]
|
|
|
|
@admin.display(description="Roles")
|
|
def roles_display(self, obj):
|
|
"""Display roles as a formatted string"""
|
|
return ", ".join(obj.roles) if obj.roles else "No roles"
|
|
|
|
@admin.display(description="Headquarters")
|
|
def headquarters_location(self, obj):
|
|
"""Display headquarters location if available"""
|
|
if hasattr(obj, "headquarters"):
|
|
return obj.headquarters.location_display
|
|
return "No headquarters"
|
|
|
|
|
|
@admin.register(ParkReview)
|
|
class ParkReviewAdmin(admin.ModelAdmin):
|
|
"""Admin interface for park reviews"""
|
|
|
|
list_display = (
|
|
"park",
|
|
"user",
|
|
"rating",
|
|
"title",
|
|
"visit_date",
|
|
"is_published",
|
|
"created_at",
|
|
"moderation_status",
|
|
)
|
|
list_filter = (
|
|
"rating",
|
|
"is_published",
|
|
"visit_date",
|
|
"created_at",
|
|
"park",
|
|
"moderated_by",
|
|
)
|
|
search_fields = (
|
|
"title",
|
|
"content",
|
|
"user__username",
|
|
"park__name",
|
|
)
|
|
readonly_fields = ("created_at", "updated_at")
|
|
date_hierarchy = "created_at"
|
|
ordering = ("-created_at",)
|
|
|
|
fieldsets = (
|
|
(
|
|
"Review Details",
|
|
{
|
|
"fields": (
|
|
"user",
|
|
"park",
|
|
"rating",
|
|
"title",
|
|
"content",
|
|
"visit_date",
|
|
)
|
|
},
|
|
),
|
|
(
|
|
"Publication Status",
|
|
{
|
|
"fields": ("is_published",),
|
|
},
|
|
),
|
|
(
|
|
"Moderation",
|
|
{
|
|
"fields": (
|
|
"moderated_by",
|
|
"moderated_at",
|
|
"moderation_notes",
|
|
),
|
|
"classes": ("collapse",),
|
|
},
|
|
),
|
|
(
|
|
"Metadata",
|
|
{
|
|
"fields": ("created_at", "updated_at"),
|
|
"classes": ("collapse",),
|
|
},
|
|
),
|
|
)
|
|
|
|
@admin.display(description="Moderation Status", boolean=True)
|
|
def moderation_status(self, obj):
|
|
"""Display moderation status with color coding"""
|
|
if obj.moderated_by:
|
|
return format_html(
|
|
'<span style="color: {};">{}</span>',
|
|
"green" if obj.is_published else "red",
|
|
"Approved" if obj.is_published else "Rejected",
|
|
)
|
|
return format_html('<span style="color: orange;">Pending</span>')
|
|
|
|
def save_model(self, request, obj, form, change):
|
|
"""Auto-set moderation info when status changes"""
|
|
if change and "is_published" in form.changed_data:
|
|
from django.utils import timezone
|
|
|
|
obj.moderated_by = request.user
|
|
obj.moderated_at = timezone.now()
|
|
super().save_model(request, obj, form, change)
|
|
|
|
|
|
@admin.register(pghistory.models.Events)
|
|
class PgHistoryEventsAdmin(admin.ModelAdmin):
|
|
"""Admin interface for pghistory Events"""
|
|
|
|
list_display = (
|
|
"pgh_id",
|
|
"pgh_created_at",
|
|
"pgh_label",
|
|
"pgh_model",
|
|
"pgh_obj_id",
|
|
"pgh_context_display",
|
|
)
|
|
list_filter = (
|
|
"pgh_label",
|
|
"pgh_model",
|
|
"pgh_created_at",
|
|
)
|
|
search_fields = (
|
|
"pgh_obj_id",
|
|
"pgh_context",
|
|
)
|
|
readonly_fields = (
|
|
"pgh_id",
|
|
"pgh_created_at",
|
|
"pgh_label",
|
|
"pgh_model",
|
|
"pgh_obj_id",
|
|
"pgh_context",
|
|
"pgh_data",
|
|
)
|
|
date_hierarchy = "pgh_created_at"
|
|
ordering = ("-pgh_created_at",)
|
|
|
|
fieldsets = (
|
|
(
|
|
"Event Information",
|
|
{
|
|
"fields": (
|
|
"pgh_id",
|
|
"pgh_created_at",
|
|
"pgh_label",
|
|
"pgh_model",
|
|
"pgh_obj_id",
|
|
)
|
|
},
|
|
),
|
|
(
|
|
"Context & Data",
|
|
{
|
|
"fields": (
|
|
"pgh_context",
|
|
"pgh_data",
|
|
),
|
|
"classes": ("collapse",),
|
|
},
|
|
),
|
|
)
|
|
|
|
@admin.display(description="Context")
|
|
def pgh_context_display(self, obj):
|
|
"""Display context information in a readable format"""
|
|
if obj.pgh_context:
|
|
if isinstance(obj.pgh_context, dict):
|
|
context_items = []
|
|
for key, value in obj.pgh_context.items():
|
|
context_items.append(f"{key}: {value}")
|
|
return ", ".join(context_items)
|
|
return str(obj.pgh_context)
|
|
return "No context"
|
|
|
|
def has_add_permission(self, request):
|
|
"""Disable manual creation of history events"""
|
|
return False
|
|
|
|
def has_change_permission(self, request, obj=None):
|
|
"""Make history events read-only"""
|
|
return False
|
|
|
|
def has_delete_permission(self, request, obj=None):
|
|
"""Prevent deletion of history events"""
|
|
return getattr(request.user, "is_superuser", False)
|
|
|
|
|
|
# Register the models with their admin classes
|
|
admin.site.register(Park, ParkAdmin)
|
|
admin.site.register(ParkArea, ParkAreaAdmin)
|
|
admin.site.register(ParkLocation, ParkLocationAdmin)
|
|
admin.site.register(Company, CompanyAdmin)
|
|
admin.site.register(CompanyHeadquarters, CompanyHeadquartersAdmin)
|