mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 10:11:13 -05:00
- Created Company model with location tracking, date precision, and CloudFlare Images - Created RideModel model for manufacturer's ride models with specifications - Created Park model with location, dates, operator, and cached statistics - Created Ride model with comprehensive stats, manufacturer, and park relationship - Created Photo model with CloudFlare Images integration and generic relations - Added lifecycle hooks for auto-slug generation and count updates - Created migrations and applied to database - Registered all models in Django admin with detailed fieldsets - Fixed admin autocomplete_fields to use raw_id_fields where needed - All models inherit from VersionedModel for automatic version tracking - Models include date precision tracking for opening/closing dates - Added comprehensive indexes for query performance Phase 1.5 complete - Entity models ready for API development
93 lines
3.0 KiB
Python
93 lines
3.0 KiB
Python
"""
|
|
Django Admin configuration for media models.
|
|
"""
|
|
from django.contrib import admin
|
|
from .models import Photo
|
|
|
|
|
|
@admin.register(Photo)
|
|
class PhotoAdmin(admin.ModelAdmin):
|
|
"""Admin interface for Photo model."""
|
|
|
|
list_display = [
|
|
'title', 'cloudflare_image_id', 'photo_type', 'moderation_status',
|
|
'is_approved', 'uploaded_by', 'created'
|
|
]
|
|
list_filter = [
|
|
'moderation_status', 'is_approved', 'photo_type',
|
|
'is_featured', 'is_public', 'created'
|
|
]
|
|
search_fields = [
|
|
'title', 'description', 'cloudflare_image_id',
|
|
'uploaded_by__email', 'uploaded_by__username'
|
|
]
|
|
readonly_fields = [
|
|
'id', 'created', 'modified', 'content_type', 'object_id',
|
|
'moderated_at'
|
|
]
|
|
raw_id_fields = ['uploaded_by', 'moderated_by']
|
|
|
|
fieldsets = (
|
|
('CloudFlare Image', {
|
|
'fields': (
|
|
'cloudflare_image_id', 'cloudflare_url',
|
|
'cloudflare_thumbnail_url'
|
|
)
|
|
}),
|
|
('Metadata', {
|
|
'fields': ('title', 'description', 'credit', 'photo_type')
|
|
}),
|
|
('Associated Entity', {
|
|
'fields': ('content_type', 'object_id')
|
|
}),
|
|
('Upload Information', {
|
|
'fields': ('uploaded_by',)
|
|
}),
|
|
('Moderation', {
|
|
'fields': (
|
|
'moderation_status', 'is_approved',
|
|
'moderated_by', 'moderated_at', 'moderation_notes'
|
|
)
|
|
}),
|
|
('Image Details', {
|
|
'fields': ('width', 'height', 'file_size'),
|
|
'classes': ('collapse',)
|
|
}),
|
|
('Display Settings', {
|
|
'fields': ('display_order', 'is_featured', 'is_public')
|
|
}),
|
|
('System', {
|
|
'fields': ('id', 'created', 'modified'),
|
|
'classes': ('collapse',)
|
|
}),
|
|
)
|
|
|
|
actions = ['approve_photos', 'reject_photos', 'flag_photos']
|
|
|
|
def approve_photos(self, request, queryset):
|
|
"""Bulk approve selected photos."""
|
|
count = 0
|
|
for photo in queryset:
|
|
photo.approve(moderator=request.user, notes='Bulk approved')
|
|
count += 1
|
|
self.message_user(request, f"{count} photo(s) approved successfully.")
|
|
approve_photos.short_description = "Approve selected photos"
|
|
|
|
def reject_photos(self, request, queryset):
|
|
"""Bulk reject selected photos."""
|
|
count = 0
|
|
for photo in queryset:
|
|
photo.reject(moderator=request.user, notes='Bulk rejected')
|
|
count += 1
|
|
self.message_user(request, f"{count} photo(s) rejected.")
|
|
reject_photos.short_description = "Reject selected photos"
|
|
|
|
def flag_photos(self, request, queryset):
|
|
"""Bulk flag selected photos for review."""
|
|
count = 0
|
|
for photo in queryset:
|
|
photo.flag(moderator=request.user, notes='Flagged for review')
|
|
count += 1
|
|
self.message_user(request, f"{count} photo(s) flagged for review.")
|
|
flag_photos.short_description = "Flag selected photos"
|