from django.contrib import admin from django.contrib.auth.admin import UserAdmin from django.utils.html import format_html from django.contrib.auth.models import Group from .models import User, UserProfile, EmailVerification, TopList, TopListItem class UserProfileInline(admin.StackedInline): model = UserProfile can_delete = False verbose_name_plural = "Profile" fieldsets = ( ( "Personal Info", {"fields": ("display_name", "avatar", "pronouns", "bio")}, ), ( "Social Media", {"fields": ("twitter", "instagram", "youtube", "discord")}, ), ( "Ride Credits", { "fields": ( "coaster_credits", "dark_ride_credits", "flat_ride_credits", "water_ride_credits", ) }, ), ) class TopListItemInline(admin.TabularInline): model = TopListItem extra = 1 fields = ("content_type", "object_id", "rank", "notes") ordering = ("rank",) @admin.register(User) class CustomUserAdmin(UserAdmin): list_display = ( "username", "email", "get_avatar", "get_status", "role", "date_joined", "last_login", "get_credits", ) list_filter = ( "is_active", "is_staff", "role", "is_banned", "groups", "date_joined", ) search_fields = ("username", "email") ordering = ("-date_joined",) actions = [ "activate_users", "deactivate_users", "ban_users", "unban_users", ] inlines = [UserProfileInline] fieldsets = ( (None, {"fields": ("username", "password")}), ("Personal info", {"fields": ("email", "pending_email")}), ( "Roles and Permissions", { "fields": ("role", "groups", "user_permissions"), "description": ( "Role determines group membership. Groups determine permissions." ), }, ), ( "Status", { "fields": ("is_active", "is_staff", "is_superuser"), "description": "These are automatically managed based on role.", }, ), ( "Ban Status", { "fields": ("is_banned", "ban_reason", "ban_date"), }, ), ( "Preferences", { "fields": ("theme_preference",), }, ), ("Important dates", {"fields": ("last_login", "date_joined")}), ) add_fieldsets = ( ( None, { "classes": ("wide",), "fields": ( "username", "email", "password1", "password2", "role", ), }, ), ) @admin.display(description="Avatar") def get_avatar(self, obj): if obj.profile.avatar: return format_html( '', obj.profile.avatar.url, ) return format_html( '
{}
', obj.username[0].upper(), ) @admin.display(description="Status") def get_status(self, obj): if obj.is_banned: return format_html('Banned') if not obj.is_active: return format_html('Inactive') if obj.is_superuser: return format_html('Superuser') if obj.is_staff: return format_html('Staff') return format_html('Active') @admin.display(description="Ride Credits") def get_credits(self, obj): try: profile = obj.profile return format_html( "RC: {}
DR: {}
FR: {}
WR: {}", profile.coaster_credits, profile.dark_ride_credits, profile.flat_ride_credits, profile.water_ride_credits, ) except UserProfile.DoesNotExist: return "-" @admin.action(description="Activate selected users") def activate_users(self, request, queryset): queryset.update(is_active=True) @admin.action(description="Deactivate selected users") def deactivate_users(self, request, queryset): queryset.update(is_active=False) @admin.action(description="Ban selected users") def ban_users(self, request, queryset): from django.utils import timezone queryset.update(is_banned=True, ban_date=timezone.now()) @admin.action(description="Unban selected users") def unban_users(self, request, queryset): queryset.update(is_banned=False, ban_date=None, ban_reason="") def save_model(self, request, obj, form, change): creating = not obj.pk super().save_model(request, obj, form, change) if creating and obj.role != User.Roles.USER: # Ensure new user with role gets added to appropriate group group = Group.objects.filter(name=obj.role).first() if group: obj.groups.add(group) @admin.register(UserProfile) class UserProfileAdmin(admin.ModelAdmin): list_display = ( "user", "display_name", "coaster_credits", "dark_ride_credits", "flat_ride_credits", "water_ride_credits", ) list_filter = ( "coaster_credits", "dark_ride_credits", "flat_ride_credits", "water_ride_credits", ) search_fields = ("user__username", "user__email", "display_name", "bio") fieldsets = ( ( "User Information", {"fields": ("user", "display_name", "avatar", "pronouns", "bio")}, ), ( "Social Media", {"fields": ("twitter", "instagram", "youtube", "discord")}, ), ( "Ride Credits", { "fields": ( "coaster_credits", "dark_ride_credits", "flat_ride_credits", "water_ride_credits", ) }, ), ) @admin.register(EmailVerification) class EmailVerificationAdmin(admin.ModelAdmin): list_display = ("user", "created_at", "last_sent", "is_expired") list_filter = ("created_at", "last_sent") search_fields = ("user__username", "user__email", "token") readonly_fields = ("created_at", "last_sent") fieldsets = ( ("Verification Details", {"fields": ("user", "token")}), ("Timing", {"fields": ("created_at", "last_sent")}), ) @admin.display(description="Status") def is_expired(self, obj): from django.utils import timezone from datetime import timedelta if timezone.now() - obj.last_sent > timedelta(days=1): return format_html('Expired') return format_html('Valid') @admin.register(TopList) class TopListAdmin(admin.ModelAdmin): list_display = ("title", "user", "category", "created_at", "updated_at") list_filter = ("category", "created_at", "updated_at") search_fields = ("title", "user__username", "description") inlines = [TopListItemInline] fieldsets = ( ( "Basic Information", {"fields": ("user", "title", "category", "description")}, ), ( "Timestamps", {"fields": ("created_at", "updated_at"), "classes": ("collapse",)}, ), ) readonly_fields = ("created_at", "updated_at") @admin.register(TopListItem) class TopListItemAdmin(admin.ModelAdmin): list_display = ("top_list", "content_type", "object_id", "rank") list_filter = ("top_list__category", "rank") search_fields = ("top_list__title", "notes") ordering = ("top_list", "rank") fieldsets = ( ("List Information", {"fields": ("top_list", "rank")}), ("Item Details", {"fields": ("content_type", "object_id", "notes")}), )