from functools import partial
from django.conf import settings
from django.contrib.auth.models import User
from django.forms.models import modelform_factory
from django.shortcuts import redirect
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
from oioioi.base import admin
from oioioi.base.menu import personal_menu_registry
from oioioi.base.permissions import is_superuser
from oioioi.contests.admin import ContestAdmin
from oioioi.teachers.forms import AdminTeacherForm, TeacherContestForm
from oioioi.teachers.models import ContestTeacher, RegistrationConfig, Teacher
[docs]
class TeacherAdmin(admin.ModelAdmin):
list_display = ["teacher_login", "teacher_email", "teacher_first_name", "teacher_last_name", "school", "is_active", "join_date"]
list_editable = ["is_active"]
search_fields = ["school", "user__username", "user__first_name", "user__last_name", "user__email", "join_date"]
form = AdminTeacherForm
change_form_template = "teachers/change_form.html"
# Override parent's function to ensure proper translation
[docs]
def get_actions(self, request):
actions = super().get_actions(request)
if "delete_selected" in actions:
function, name, short_description = actions["delete_selected"]
new_description = _("Delete selected teachers")
actions["delete_selected"] = (function, name, new_description)
return actions
[docs]
def has_add_permission(self, request):
return request.user.is_superuser
[docs]
def has_change_permission(self, request, obj=None):
return self.has_add_permission(request)
[docs]
def has_delete_permission(self, request, obj=None):
return self.has_add_permission(request)
[docs]
def teacher_first_name(self, instance):
if not instance.user:
return ""
return instance.user.first_name
[docs]
def teacher_last_name(self, instance):
if not instance.user:
return ""
return instance.user.last_name
[docs]
def teacher_email(self, instance):
if not instance.user:
return ""
return instance.user.email
[docs]
def teacher_login(self, instance):
if not instance.user:
return ""
return instance.user.get_username()
teacher_first_name.short_description = _("First name")
teacher_last_name.short_description = _("Last name")
teacher_email.short_description = _("Email address")
teacher_login.short_description = _("Username")
admin.site.register(Teacher, TeacherAdmin)
admin.system_admin_menu_registry.register(
"teachers",
_("Teachers"),
lambda request: reverse("oioioiadmin:teachers_teacher_changelist"),
condition=is_superuser,
order=20,
)
[docs]
class ContestAdminMixin:
"""Adjusts contest admin panel for teachers app usage. Superusers continue
to work as usual but teachers have special options.
"""
[docs]
def has_add_permission(self, request):
if request.user.has_perm("teachers.teacher"):
return True
return super().has_add_permission(request)
[docs]
def save_model(self, request, obj, form, change):
# Superusers are allowed to add contest of any type.
# Teachers may only add TeacherContests. The type should be
# set only if the contest is created - if it's modified we
# don't want to change the current type.
if request.user.has_perm("teachers.teacher") and (not change and not request.user.is_superuser):
obj.controller_name = "oioioi.teachers.controllers.TeacherContestController"
super().save_model(request, obj, form, change)
if not change and request.user.has_perm("teachers.teacher"):
try:
teacher_obj = Teacher.objects.get(user=request.user)
ContestTeacher.objects.get_or_create(contest=obj, teacher=teacher_obj)
RegistrationConfig.objects.get_or_create(contest=obj)
except Teacher.DoesNotExist:
pass
[docs]
def get_fieldsets(self, request, obj=None):
if obj or request.user.is_superuser or not request.user.has_perm("teachers.teacher"):
return super().get_fieldsets(request, obj)
fields = list(TeacherContestForm().base_fields.keys())
return [(None, {"fields": fields})]
[docs]
def response_add(self, request, obj, post_url_continue=None):
if request.user.is_superuser or not request.user.has_perm("teachers.teacher"):
return super().response_add(request, obj, post_url_continue)
self.message_user(request, _("Contest added successfully."))
return redirect("show_members", contest_id=obj.id, member_type="pupil")
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
ContestAdmin.mix_in(ContestAdminMixin)
if "oioioi.simpleui" not in settings.INSTALLED_APPS:
personal_menu_registry.register(
"create_contest",
_("New contest"),
lambda request: reverse("oioioiadmin:contests_contest_add"),
lambda request: request.user.has_perm("teachers.teacher"),
order=10,
)
else:
personal_menu_registry.register(
"teacher_dashboard",
_("Contests"),
lambda request: reverse("teacher_dashboard"),
lambda request: request.user.has_perm("teachers.teacher"),
order=5,
)