from django.contrib import admin from django.contrib.gis.admin import GISModelAdmin 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(GISModelAdmin): """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( '{}', "green" if obj.is_published else "red", "Approved" if obj.is_published else "Rejected", ) return format_html('Pending') 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)