NDOJ/judge/admin/interface.py

237 lines
7.4 KiB
Python
Raw Permalink Normal View History

2020-01-21 06:35:58 +00:00
from django.contrib import admin
from django.contrib.auth.models import User
from django.forms import ModelForm
from django.urls import NoReverseMatch, reverse, reverse_lazy
from django.utils.html import format_html
from django.utils.translation import gettext_lazy as _
from mptt.admin import DraggableMPTTAdmin
from reversion.admin import VersionAdmin
from reversion_compare.admin import CompareVersionAdmin
2020-01-21 06:35:58 +00:00
from judge.dblock import LockModel
from judge.models import NavigationBar
2022-05-14 17:57:27 +00:00
from judge.widgets import (
AdminHeavySelect2MultipleWidget,
AdminHeavySelect2Widget,
HeavyPreviewAdminPageDownWidget,
)
2020-01-21 06:35:58 +00:00
class NavigationBarAdmin(DraggableMPTTAdmin):
2022-05-14 17:57:27 +00:00
list_display = DraggableMPTTAdmin.list_display + ("key", "linked_path")
fields = ("key", "label", "path", "order", "regex", "parent")
2020-01-21 06:35:58 +00:00
list_editable = () # Bug in SortableModelAdmin: 500 without list_editable being set
mptt_level_indent = 20
2022-05-14 17:57:27 +00:00
sortable = "order"
2020-01-21 06:35:58 +00:00
def __init__(self, *args, **kwargs):
super(NavigationBarAdmin, self).__init__(*args, **kwargs)
self.__save_model_calls = 0
def linked_path(self, obj):
2022-05-14 17:57:27 +00:00
return format_html('<a href="{0}" target="_blank">{0}</a>', obj.path)
linked_path.short_description = _("link path")
2020-01-21 06:35:58 +00:00
def save_model(self, request, obj, form, change):
self.__save_model_calls += 1
return super(NavigationBarAdmin, self).save_model(request, obj, form, change)
def changelist_view(self, request, extra_context=None):
self.__save_model_calls = 0
with NavigationBar.objects.disable_mptt_updates():
2022-05-14 17:57:27 +00:00
result = super(NavigationBarAdmin, self).changelist_view(
request, extra_context
)
2020-01-21 06:35:58 +00:00
if self.__save_model_calls:
with LockModel(write=(NavigationBar,)):
NavigationBar.objects.rebuild()
return result
class BlogPostForm(ModelForm):
def __init__(self, *args, **kwargs):
super(BlogPostForm, self).__init__(*args, **kwargs)
2024-06-01 06:37:29 +00:00
if "authors" in self.fields:
self.fields["authors"].widget.can_add_related = False
2020-01-21 06:35:58 +00:00
class Meta:
widgets = {
2022-05-14 17:57:27 +00:00
"authors": AdminHeavySelect2MultipleWidget(
data_view="profile_select2", attrs={"style": "width: 100%"}
),
"organizations": AdminHeavySelect2MultipleWidget(
data_view="organization_select2", attrs={"style": "width: 100%"}
),
2020-01-21 06:35:58 +00:00
}
if HeavyPreviewAdminPageDownWidget is not None:
2022-05-14 17:57:27 +00:00
widgets["content"] = HeavyPreviewAdminPageDownWidget(
preview=reverse_lazy("blog_preview")
)
widgets["summary"] = HeavyPreviewAdminPageDownWidget(
preview=reverse_lazy("blog_preview")
)
2020-01-21 06:35:58 +00:00
class BlogPostAdmin(CompareVersionAdmin):
2020-01-21 06:35:58 +00:00
fieldsets = (
2022-05-14 17:57:27 +00:00
(
None,
{
"fields": (
"title",
"slug",
"authors",
"visible",
"sticky",
"publish_on",
"is_organization_private",
"organizations",
)
},
),
(_("Content"), {"fields": ("content", "og_image")}),
(_("Summary"), {"classes": ("collapse",), "fields": ("summary",)}),
2020-01-21 06:35:58 +00:00
)
2022-05-14 17:57:27 +00:00
prepopulated_fields = {"slug": ("title",)}
list_display = ("id", "title", "visible", "sticky", "publish_on")
list_display_links = ("id", "title")
ordering = ("-publish_on",)
2020-01-21 06:35:58 +00:00
form = BlogPostForm
2022-05-14 17:57:27 +00:00
date_hierarchy = "publish_on"
2020-01-21 06:35:58 +00:00
def has_change_permission(self, request, obj=None):
2022-05-14 17:57:27 +00:00
return (
request.user.has_perm("judge.edit_all_post")
or request.user.has_perm("judge.change_blogpost")
and (obj is None or obj.authors.filter(id=request.profile.id).exists())
)
2020-01-21 06:35:58 +00:00
class SolutionForm(ModelForm):
def __init__(self, *args, **kwargs):
super(SolutionForm, self).__init__(*args, **kwargs)
2022-05-14 17:57:27 +00:00
self.fields["authors"].widget.can_add_related = False
2020-01-21 06:35:58 +00:00
class Meta:
widgets = {
2022-05-14 17:57:27 +00:00
"authors": AdminHeavySelect2MultipleWidget(
data_view="profile_select2", attrs={"style": "width: 100%"}
),
"problem": AdminHeavySelect2Widget(
data_view="problem_select2", attrs={"style": "width: 250px"}
),
2020-01-21 06:35:58 +00:00
}
if HeavyPreviewAdminPageDownWidget is not None:
2022-05-14 17:57:27 +00:00
widgets["content"] = HeavyPreviewAdminPageDownWidget(
preview=reverse_lazy("solution_preview")
)
2020-01-21 06:35:58 +00:00
class LicenseForm(ModelForm):
class Meta:
if HeavyPreviewAdminPageDownWidget is not None:
2022-05-14 17:57:27 +00:00
widgets = {
"text": HeavyPreviewAdminPageDownWidget(
preview=reverse_lazy("license_preview")
)
}
2020-01-21 06:35:58 +00:00
class LicenseAdmin(admin.ModelAdmin):
2022-05-14 17:57:27 +00:00
fields = ("key", "link", "name", "display", "icon", "text")
list_display = ("name", "key")
2020-01-21 06:35:58 +00:00
form = LicenseForm
class UserListFilter(admin.SimpleListFilter):
2022-05-14 17:57:27 +00:00
title = _("user")
parameter_name = "user"
2020-01-21 06:35:58 +00:00
def lookups(self, request, model_admin):
2022-05-14 17:57:27 +00:00
return User.objects.filter(is_staff=True).values_list("id", "username")
2020-01-21 06:35:58 +00:00
def queryset(self, request, queryset):
if self.value():
return queryset.filter(user_id=self.value(), user__is_staff=True)
return queryset
class LogEntryAdmin(admin.ModelAdmin):
2022-05-14 17:57:27 +00:00
readonly_fields = (
"user",
"content_type",
"object_id",
"object_repr",
"action_flag",
"change_message",
)
list_display = (
"__str__",
"action_time",
"user",
"content_type",
"object_link",
"diff_link",
)
2022-09-04 17:32:10 +00:00
search_fields = (
"object_repr",
"change_message",
"user__username",
"content_type__model",
)
2022-05-14 17:57:27 +00:00
list_filter = (UserListFilter, "content_type")
2020-01-21 06:35:58 +00:00
list_display_links = None
actions = None
def has_add_permission(self, request):
return False
def has_change_permission(self, request, obj=None):
return obj is None and request.user.is_superuser
def has_delete_permission(self, request, obj=None):
return False
def object_link(self, obj):
if obj.is_deletion():
link = obj.object_repr
else:
ct = obj.content_type
try:
2022-05-14 17:57:27 +00:00
link = format_html(
'<a href="{1}">{0}</a>',
obj.object_repr,
reverse(
"admin:%s_%s_change" % (ct.app_label, ct.model),
args=(obj.object_id,),
),
)
2020-01-21 06:35:58 +00:00
except NoReverseMatch:
link = obj.object_repr
return link
2022-05-14 17:57:27 +00:00
object_link.admin_order_field = "object_repr"
object_link.short_description = _("object")
2020-01-21 06:35:58 +00:00
def diff_link(self, obj):
if obj.is_deletion():
return None
ct = obj.content_type
try:
2022-05-14 17:57:27 +00:00
url = reverse(
"admin:%s_%s_history" % (ct.app_label, ct.model), args=(obj.object_id,)
)
link = format_html('<a href="{1}">{0}</a>', _("Diff"), url)
except NoReverseMatch:
link = None
return link
2022-05-14 17:57:27 +00:00
diff_link.short_description = _("diff")
2020-01-21 06:35:58 +00:00
def queryset(self, request):
2022-09-04 17:32:10 +00:00
return super().queryset(request).prefetch_related("content_type")