mirror of
https://github.com/DMOJ/online-judge.git
synced 2024-11-25 16:32:37 +08:00
Use decorator for admin display functions
This commit is contained in:
parent
138ce7fc99
commit
79be4af4b5
@ -1,3 +1,4 @@
|
||||
from django.contrib import admin
|
||||
from django.db.models import F
|
||||
from django.forms import ModelForm
|
||||
from django.urls import reverse_lazy
|
||||
@ -36,28 +37,27 @@ class CommentAdmin(VersionAdmin):
|
||||
def get_queryset(self, request):
|
||||
return Comment.objects.order_by('-time')
|
||||
|
||||
@admin.display(description=_('Hide comments'))
|
||||
def hide_comment(self, request, queryset):
|
||||
count = queryset.update(hidden=True)
|
||||
self.message_user(request, ngettext('%d comment successfully hidden.',
|
||||
'%d comments successfully hidden.',
|
||||
count) % count)
|
||||
hide_comment.short_description = _('Hide comments')
|
||||
|
||||
@admin.display(description=_('Unhide comments'))
|
||||
def unhide_comment(self, request, queryset):
|
||||
count = queryset.update(hidden=False)
|
||||
self.message_user(request, ngettext('%d comment successfully unhidden.',
|
||||
'%d comments successfully unhidden.',
|
||||
count) % count)
|
||||
unhide_comment.short_description = _('Unhide comments')
|
||||
|
||||
@admin.display(description=_('Associated page'), ordering='page')
|
||||
def linked_page(self, obj):
|
||||
link = obj.link
|
||||
if link is not None:
|
||||
return format_html('<a href="{0}">{1}</a>', link, obj.page)
|
||||
else:
|
||||
return format_html('{0}', obj.page)
|
||||
linked_page.short_description = _('Associated page')
|
||||
linked_page.admin_order_field = 'page'
|
||||
|
||||
def save_model(self, request, obj, form, change):
|
||||
obj.revisions = F('revisions') + 1
|
||||
|
@ -69,12 +69,12 @@ class ContestProblemInline(SortableInlineAdminMixin, admin.TabularInline):
|
||||
readonly_fields = ('rejudge_column',)
|
||||
form = ContestProblemInlineForm
|
||||
|
||||
@admin.display(description='')
|
||||
def rejudge_column(self, obj):
|
||||
if obj.id is None:
|
||||
return ''
|
||||
return format_html('<a class="button rejudge-link" href="{0}">{1}</a>',
|
||||
reverse('admin:judge_contest_rejudge', args=(obj.contest.id, obj.id)), _('Rejudge'))
|
||||
rejudge_column.short_description = ''
|
||||
|
||||
|
||||
class ContestForm(ModelForm):
|
||||
@ -222,6 +222,7 @@ class ContestAdmin(NoBatchDeleteMixin, VersionAdmin):
|
||||
from judge.tasks import rescore_contest
|
||||
transaction.on_commit(rescore_contest.s(contest_key).delay)
|
||||
|
||||
@admin.display(description=_('Mark contests as visible'))
|
||||
def make_visible(self, request, queryset):
|
||||
if not request.user.has_perm('judge.change_contest_visibility'):
|
||||
queryset = queryset.filter(Q(is_private=True) | Q(is_organization_private=True))
|
||||
@ -229,8 +230,8 @@ class ContestAdmin(NoBatchDeleteMixin, VersionAdmin):
|
||||
self.message_user(request, ngettext('%d contest successfully marked as visible.',
|
||||
'%d contests successfully marked as visible.',
|
||||
count) % count)
|
||||
make_visible.short_description = _('Mark contests as visible')
|
||||
|
||||
@admin.display(description=_('Mark contests as hidden'))
|
||||
def make_hidden(self, request, queryset):
|
||||
if not request.user.has_perm('judge.change_contest_visibility'):
|
||||
queryset = queryset.filter(Q(is_private=True) | Q(is_organization_private=True))
|
||||
@ -238,8 +239,8 @@ class ContestAdmin(NoBatchDeleteMixin, VersionAdmin):
|
||||
self.message_user(request, ngettext('%d contest successfully marked as hidden.',
|
||||
'%d contests successfully marked as hidden.',
|
||||
count) % count)
|
||||
make_hidden.short_description = _('Mark contests as hidden')
|
||||
|
||||
@admin.display(description=_('Lock contest submissions'))
|
||||
def set_locked(self, request, queryset):
|
||||
for row in queryset:
|
||||
self.set_locked_after(row, timezone.now())
|
||||
@ -247,8 +248,8 @@ class ContestAdmin(NoBatchDeleteMixin, VersionAdmin):
|
||||
self.message_user(request, ngettext('%d contest successfully locked.',
|
||||
'%d contests successfully locked.',
|
||||
count) % count)
|
||||
set_locked.short_description = _('Lock contest submissions')
|
||||
|
||||
@admin.display(description=_('Unlock contest submissions'))
|
||||
def set_unlocked(self, request, queryset):
|
||||
for row in queryset:
|
||||
self.set_locked_after(row, None)
|
||||
@ -256,7 +257,6 @@ class ContestAdmin(NoBatchDeleteMixin, VersionAdmin):
|
||||
self.message_user(request, ngettext('%d contest successfully unlocked.',
|
||||
'%d contests successfully unlocked.',
|
||||
count) % count)
|
||||
set_unlocked.short_description = _('Unlock contest submissions')
|
||||
|
||||
def set_locked_after(self, contest, locked_after):
|
||||
with transaction.atomic():
|
||||
@ -350,6 +350,7 @@ class ContestParticipationAdmin(admin.ModelAdmin):
|
||||
if form.changed_data and 'is_disqualified' in form.changed_data:
|
||||
obj.set_disqualified(obj.is_disqualified)
|
||||
|
||||
@admin.display(description=_('Recalculate results'))
|
||||
def recalculate_results(self, request, queryset):
|
||||
count = 0
|
||||
for participation in queryset:
|
||||
@ -358,14 +359,11 @@ class ContestParticipationAdmin(admin.ModelAdmin):
|
||||
self.message_user(request, ngettext('%d participation recalculated.',
|
||||
'%d participations recalculated.',
|
||||
count) % count)
|
||||
recalculate_results.short_description = _('Recalculate results')
|
||||
|
||||
@admin.display(description=_('username'), ordering='user__user__username')
|
||||
def username(self, obj):
|
||||
return obj.user.username
|
||||
username.short_description = _('username')
|
||||
username.admin_order_field = 'user__user__username'
|
||||
|
||||
@admin.display(description=_('virtual'), ordering='virtual')
|
||||
def show_virtual(self, obj):
|
||||
return obj.virtual or '-'
|
||||
show_virtual.short_description = _('virtual')
|
||||
show_virtual.admin_order_field = 'virtual'
|
||||
|
@ -25,9 +25,9 @@ class NavigationBarAdmin(DraggableMPTTAdmin):
|
||||
super(NavigationBarAdmin, self).__init__(*args, **kwargs)
|
||||
self.__save_model_calls = 0
|
||||
|
||||
@admin.display(description=_('link path'))
|
||||
def linked_path(self, obj):
|
||||
return format_html('<a href="{0}" target="_blank">{0}</a>', obj.path)
|
||||
linked_path.short_description = _('link path')
|
||||
|
||||
def save_model(self, request, obj, form, change):
|
||||
self.__save_model_calls += 1
|
||||
@ -151,6 +151,7 @@ class LogEntryAdmin(admin.ModelAdmin):
|
||||
def has_delete_permission(self, request, obj=None):
|
||||
return False
|
||||
|
||||
@admin.display(description=_('object'), ordering='object_repr')
|
||||
def object_link(self, obj):
|
||||
if obj.is_deletion():
|
||||
link = obj.object_repr
|
||||
@ -162,8 +163,6 @@ class LogEntryAdmin(admin.ModelAdmin):
|
||||
except NoReverseMatch:
|
||||
link = obj.object_repr
|
||||
return link
|
||||
object_link.admin_order_field = 'object_repr'
|
||||
object_link.short_description = _('object')
|
||||
|
||||
def queryset(self, request):
|
||||
return super().queryset(request).prefetch_related('content_type')
|
||||
|
@ -77,12 +77,11 @@ class OrganizationAdmin(VersionAdmin):
|
||||
actions_on_bottom = True
|
||||
form = OrganizationForm
|
||||
|
||||
@admin.display(description='')
|
||||
def show_public(self, obj):
|
||||
return format_html('<a href="{0}" style="white-space:nowrap;">{1}</a>',
|
||||
obj.get_absolute_url(), gettext('View on site'))
|
||||
|
||||
show_public.short_description = ''
|
||||
|
||||
def get_readonly_fields(self, request, obj=None):
|
||||
fields = self.readonly_fields
|
||||
if not request.user.has_perm('judge.organization_admin'):
|
||||
@ -108,7 +107,6 @@ class OrganizationRequestAdmin(admin.ModelAdmin):
|
||||
list_display = ('username', 'organization', 'state', 'time')
|
||||
readonly_fields = ('user', 'organization', 'request_class')
|
||||
|
||||
@admin.display(description=_('username'), ordering='user__user__username')
|
||||
def username(self, obj):
|
||||
return obj.user.user.username
|
||||
username.short_description = _('username')
|
||||
username.admin_order_field = 'user__user__username'
|
||||
|
@ -174,28 +174,26 @@ class ProblemAdmin(NoBatchDeleteMixin, VersionAdmin):
|
||||
fields += ('description',)
|
||||
return fields
|
||||
|
||||
@admin.display(description=_('Authors'))
|
||||
def show_authors(self, obj):
|
||||
return ', '.join(map(attrgetter('user.username'), obj.authors.all()))
|
||||
|
||||
show_authors.short_description = _('Authors')
|
||||
|
||||
@admin.display(description='')
|
||||
def show_public(self, obj):
|
||||
return format_html('<a href="{1}">{0}</a>', gettext('View on site'), obj.get_absolute_url())
|
||||
|
||||
show_public.short_description = ''
|
||||
|
||||
def _rescore(self, request, problem_id):
|
||||
from judge.tasks import rescore_problem
|
||||
transaction.on_commit(rescore_problem.s(problem_id).delay)
|
||||
|
||||
@admin.display(description=_('Set publish date to now'))
|
||||
def update_publish_date(self, request, queryset):
|
||||
count = queryset.update(date=timezone.now())
|
||||
self.message_user(request, ngettext("%d problem's publish date successfully updated.",
|
||||
"%d problems' publish date successfully updated.",
|
||||
count) % count)
|
||||
|
||||
update_publish_date.short_description = _('Set publish date to now')
|
||||
|
||||
@admin.display(description=_('Mark problems as public'))
|
||||
def make_public(self, request, queryset):
|
||||
count = queryset.update(is_public=True)
|
||||
for problem_id in queryset.values_list('id', flat=True):
|
||||
@ -204,8 +202,7 @@ class ProblemAdmin(NoBatchDeleteMixin, VersionAdmin):
|
||||
'%d problems successfully marked as public.',
|
||||
count) % count)
|
||||
|
||||
make_public.short_description = _('Mark problems as public')
|
||||
|
||||
@admin.display(description=_('Mark problems as private'))
|
||||
def make_private(self, request, queryset):
|
||||
count = queryset.update(is_public=False)
|
||||
for problem_id in queryset.values_list('id', flat=True):
|
||||
@ -214,8 +211,6 @@ class ProblemAdmin(NoBatchDeleteMixin, VersionAdmin):
|
||||
'%d problems successfully marked as private.',
|
||||
count) % count)
|
||||
|
||||
make_private.short_description = _('Mark problems as private')
|
||||
|
||||
def get_queryset(self, request):
|
||||
return Problem.get_editable_problems(request.user).prefetch_related('authors__user').distinct()
|
||||
|
||||
@ -270,8 +265,7 @@ class ProblemPointsVoteAdmin(admin.ModelAdmin):
|
||||
def lookup_allowed(self, key, value):
|
||||
return super().lookup_allowed(key, value) or key in ('problem__code',)
|
||||
|
||||
@admin.display(description=_('problem'), ordering='problem__name')
|
||||
def linked_problem(self, obj):
|
||||
link = reverse('problem_detail', args=[obj.problem.code])
|
||||
return format_html('<a href="{0}">{1}</a>', link, obj.problem.name)
|
||||
linked_problem.short_description = _('problem')
|
||||
linked_problem.admin_order_field = 'problem__name'
|
||||
|
@ -87,31 +87,28 @@ class ProfileAdmin(NoBatchDeleteMixin, VersionAdmin):
|
||||
fields += ('is_totp_enabled',)
|
||||
return fields
|
||||
|
||||
@admin.display(description='')
|
||||
def show_public(self, obj):
|
||||
return format_html('<a href="{0}" style="white-space:nowrap;">{1}</a>',
|
||||
obj.get_absolute_url(), gettext('View on site'))
|
||||
show_public.short_description = ''
|
||||
|
||||
@admin.display(description=_('User'), ordering='user__username')
|
||||
def admin_user_admin(self, obj):
|
||||
return obj.username
|
||||
admin_user_admin.admin_order_field = 'user__username'
|
||||
admin_user_admin.short_description = _('User')
|
||||
|
||||
@admin.display(description=_('Email'), ordering='user__email')
|
||||
def email(self, obj):
|
||||
return obj.user.email
|
||||
email.admin_order_field = 'user__email'
|
||||
email.short_description = _('Email')
|
||||
|
||||
@admin.display(description=_('Timezone'), ordering='timezone')
|
||||
def timezone_full(self, obj):
|
||||
return obj.timezone
|
||||
timezone_full.admin_order_field = 'timezone'
|
||||
timezone_full.short_description = _('Timezone')
|
||||
|
||||
@admin.display(description=_('date joined'), ordering='user__date_joined')
|
||||
def date_joined(self, obj):
|
||||
return obj.user.date_joined
|
||||
date_joined.admin_order_field = 'user__date_joined'
|
||||
date_joined.short_description = _('date joined')
|
||||
|
||||
@admin.display(description=_('Recalculate scores'))
|
||||
def recalculate_points(self, request, queryset):
|
||||
count = 0
|
||||
for profile in queryset:
|
||||
@ -120,7 +117,6 @@ class ProfileAdmin(NoBatchDeleteMixin, VersionAdmin):
|
||||
self.message_user(request, ngettext('%d user had scores recalculated.',
|
||||
'%d users had scores recalculated.',
|
||||
count) % count)
|
||||
recalculate_points.short_description = _('Recalculate scores')
|
||||
|
||||
def get_form(self, request, obj=None, **kwargs):
|
||||
form = super(ProfileAdmin, self).get_form(request, obj, **kwargs)
|
||||
|
@ -156,6 +156,7 @@ class SubmissionAdmin(VersionAdmin):
|
||||
def lookup_allowed(self, key, value):
|
||||
return super(SubmissionAdmin, self).lookup_allowed(key, value) or key in ('problem__code',)
|
||||
|
||||
@admin.display(description=_('Rejudge the selected submissions'))
|
||||
def judge(self, request, queryset):
|
||||
if not request.user.has_perm('judge.rejudge_submission') or not request.user.has_perm('judge.edit_own_problem'):
|
||||
self.message_user(request, gettext('You do not have the permission to rejudge submissions.'),
|
||||
@ -176,8 +177,8 @@ class SubmissionAdmin(VersionAdmin):
|
||||
self.message_user(request, ngettext('%d submission was successfully scheduled for rejudging.',
|
||||
'%d submissions were successfully scheduled for rejudging.',
|
||||
judged) % judged)
|
||||
judge.short_description = _('Rejudge the selected submissions')
|
||||
|
||||
@admin.display(description=_('Rescore the selected submissions'))
|
||||
def recalculate_score(self, request, queryset):
|
||||
if not request.user.has_perm('judge.rejudge_submission'):
|
||||
self.message_user(request, gettext('You do not have the permission to rejudge submissions.'),
|
||||
@ -205,28 +206,24 @@ class SubmissionAdmin(VersionAdmin):
|
||||
self.message_user(request, ngettext('%d submission was successfully rescored.',
|
||||
'%d submissions were successfully rescored.',
|
||||
len(submissions)) % len(submissions))
|
||||
recalculate_score.short_description = _('Rescore the selected submissions')
|
||||
|
||||
@admin.display(description=_('Problem code'), ordering='problem__code')
|
||||
def problem_code(self, obj):
|
||||
return obj.problem.code
|
||||
problem_code.short_description = _('Problem code')
|
||||
problem_code.admin_order_field = 'problem__code'
|
||||
|
||||
@admin.display(description=_('Problem name'), ordering='problem__name')
|
||||
def problem_name(self, obj):
|
||||
return obj.problem.name
|
||||
problem_name.short_description = _('Problem name')
|
||||
problem_name.admin_order_field = 'problem__name'
|
||||
|
||||
@admin.display(description=_('User'), ordering='user__user__username')
|
||||
def user_column(self, obj):
|
||||
return obj.user.user.username
|
||||
user_column.admin_order_field = 'user__user__username'
|
||||
user_column.short_description = _('User')
|
||||
|
||||
@admin.display(description=_('Time'), ordering='time')
|
||||
def execution_time(self, obj):
|
||||
return round(obj.time, 2) if obj.time is not None else 'None'
|
||||
execution_time.short_description = _('Time')
|
||||
execution_time.admin_order_field = 'time'
|
||||
|
||||
@admin.display(description=_('Memory'), ordering='memory')
|
||||
def pretty_memory(self, obj):
|
||||
memory = obj.memory
|
||||
if memory is None:
|
||||
@ -235,21 +232,18 @@ class SubmissionAdmin(VersionAdmin):
|
||||
return gettext('%d KB') % memory
|
||||
else:
|
||||
return gettext('%.2f MB') % (memory / 1024)
|
||||
pretty_memory.admin_order_field = 'memory'
|
||||
pretty_memory.short_description = _('Memory')
|
||||
|
||||
@admin.display(description=_('Language'), ordering='language__name')
|
||||
def language_column(self, obj):
|
||||
return obj.language.name
|
||||
language_column.admin_order_field = 'language__name'
|
||||
language_column.short_description = _('Language')
|
||||
|
||||
@admin.display(description='')
|
||||
def judge_column(self, obj):
|
||||
if obj.is_locked:
|
||||
return format_html('<input type="button" disabled value="{0}"/>', _('Locked'))
|
||||
else:
|
||||
return format_html('<input type="button" value="{0}" onclick="location.href=\'{1}\'"/>', _('Rejudge'),
|
||||
reverse('admin:judge_submission_rejudge', args=(obj.id,)))
|
||||
judge_column.short_description = ''
|
||||
|
||||
def get_urls(self):
|
||||
return [
|
||||
|
Loading…
Reference in New Issue
Block a user