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
|
2022-04-26 18:24:36 +00:00
|
|
|
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
|
|
|
|
|
|
|
|
2022-04-26 18:24:36 +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
|
|
|
|
2022-04-26 18:24:36 +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)
|
2022-04-26 18:24:36 +00:00
|
|
|
except NoReverseMatch:
|
|
|
|
link = None
|
|
|
|
return link
|
2022-05-14 17:57:27 +00:00
|
|
|
|
|
|
|
diff_link.short_description = _("diff")
|
2022-04-26 18:24:36 +00:00
|
|
|
|
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")
|