mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 07:11:08 -05:00
202 lines
7.3 KiB
Python
202 lines
7.3 KiB
Python
from django.contrib import admin
|
|
from django.contrib.auth.admin import UserAdmin
|
|
from django.utils.html import format_html
|
|
from django.urls import reverse
|
|
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_status', 'role', 'date_joined', 'last_login', 'get_credits')
|
|
list_filter = ('is_active', 'is_staff', 'role', 'is_banned', 'groups', 'date_joined')
|
|
search_fields = ('username', 'email', 'first_name', 'last_name')
|
|
ordering = ('-date_joined',)
|
|
actions = ['activate_users', 'deactivate_users', 'ban_users', 'unban_users']
|
|
inlines = [UserProfileInline]
|
|
|
|
fieldsets = (
|
|
(None, {'fields': ('username', 'password')}),
|
|
('Personal info', {'fields': ('first_name', 'last_name', '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'),
|
|
}),
|
|
)
|
|
|
|
def get_status(self, obj):
|
|
if obj.is_banned:
|
|
return format_html('<span style="color: red;">Banned</span>')
|
|
if not obj.is_active:
|
|
return format_html('<span style="color: orange;">Inactive</span>')
|
|
if obj.is_superuser:
|
|
return format_html('<span style="color: purple;">Superuser</span>')
|
|
if obj.is_staff:
|
|
return format_html('<span style="color: blue;">Staff</span>')
|
|
return format_html('<span style="color: green;">Active</span>')
|
|
get_status.short_description = 'Status'
|
|
|
|
def get_credits(self, obj):
|
|
try:
|
|
profile = obj.profile
|
|
return format_html(
|
|
'RC: {}<br>DR: {}<br>FR: {}<br>WR: {}',
|
|
profile.coaster_credits,
|
|
profile.dark_ride_credits,
|
|
profile.flat_ride_credits,
|
|
profile.water_ride_credits
|
|
)
|
|
except UserProfile.DoesNotExist:
|
|
return '-'
|
|
get_credits.short_description = 'Ride Credits'
|
|
|
|
def activate_users(self, request, queryset):
|
|
queryset.update(is_active=True)
|
|
activate_users.short_description = "Activate selected users"
|
|
|
|
def deactivate_users(self, request, queryset):
|
|
queryset.update(is_active=False)
|
|
deactivate_users.short_description = "Deactivate selected users"
|
|
|
|
def ban_users(self, request, queryset):
|
|
from django.utils import timezone
|
|
queryset.update(is_banned=True, ban_date=timezone.now())
|
|
ban_users.short_description = "Ban selected users"
|
|
|
|
def unban_users(self, request, queryset):
|
|
queryset.update(is_banned=False, ban_date=None, ban_reason='')
|
|
unban_users.short_description = "Unban selected users"
|
|
|
|
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')
|
|
}),
|
|
)
|
|
|
|
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('<span style="color: red;">Expired</span>')
|
|
return format_html('<span style="color: green;">Valid</span>')
|
|
is_expired.short_description = 'Status'
|
|
|
|
@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')
|
|
}),
|
|
)
|