diff --git a/judge/admin/__init__.py b/judge/admin/__init__.py index 6709cc6b58..a5dd203b1a 100644 --- a/judge/admin/__init__.py +++ b/judge/admin/__init__.py @@ -1,5 +1,6 @@ from django.contrib import admin from django.contrib.admin.models import LogEntry +from django.contrib.auth.models import User from django.contrib.flatpages.models import FlatPage from judge.admin.comments import CommentAdmin @@ -7,7 +8,7 @@ from judge.admin.interface import BlogPostAdmin, FlatPageAdmin, LicenseAdmin, LogEntryAdmin, NavigationBarAdmin from judge.admin.organization import ClassAdmin, OrganizationAdmin, OrganizationRequestAdmin from judge.admin.problem import ProblemAdmin, ProblemPointsVoteAdmin -from judge.admin.profile import ProfileAdmin +from judge.admin.profile import ProfileAdmin, UserAdmin from judge.admin.runtime import JudgeAdmin, LanguageAdmin from judge.admin.submission import SubmissionAdmin from judge.admin.taxon import ProblemGroupAdmin, ProblemTypeAdmin @@ -40,3 +41,5 @@ admin.site.register(Profile, ProfileAdmin) admin.site.register(Submission, SubmissionAdmin) admin.site.register(Ticket, TicketAdmin) +admin.site.unregister(User) +admin.site.register(User, UserAdmin) diff --git a/judge/admin/profile.py b/judge/admin/profile.py index 67466e5c1c..92692c3677 100644 --- a/judge/admin/profile.py +++ b/judge/admin/profile.py @@ -1,4 +1,5 @@ from django.contrib import admin +from django.contrib.auth.admin import UserAdmin as OldUserAdmin from django.forms import ModelForm from django.urls import reverse_lazy from django.utils.html import format_html @@ -69,6 +70,17 @@ class ProfileAdmin(NoBatchDeleteMixin, VersionAdmin): form = ProfileForm inlines = [WebAuthnInline] + def has_add_permission(self, request, obj=None): + return False + + # We can't use has_delete_permission here because we still want user profiles to be + # deleteable through related objects (i.e. User). Thus, we simply hide the delete button. + # If an admin wants to go directly to the delete endpoint to delete a profile, more + # power to them. + def render_change_form(self, request, context, **kwargs): + context.update({'show_delete': False}) + return super().render_change_form(request, context, **kwargs) + def get_queryset(self, request): return super(ProfileAdmin, self).get_queryset(request).select_related('user') @@ -126,3 +138,10 @@ def get_form(self, request, obj=None, **kwargs): mode='javascript', theme=request.profile.resolved_ace_theme, ) return form + + +class UserAdmin(OldUserAdmin): + def save_model(self, request, obj, form, change): + super().save_model(request, obj, form, change) + if not change: + Profile.objects.create(user=obj)